[Rt-commit] rt branch, 3.9-lifecycles_improvments_v2, created. rt-3.9.4-494-g022930e

Ruslan Zakirov ruz at bestpractical.com
Mon Nov 15 08:29:26 EST 2010


The branch, 3.9-lifecycles_improvments_v2 has been created
        at  022930e7240c8116e49fb14962dbc59f78be3b07 (commit)

- Log -----------------------------------------------------------------
commit 7494a3e1a25b8de6fb92c11712aa05c84dab05d3
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 5 07:38:08 2010 +0300

    RT::Queue->lifecycle -> RT::Queue->Lifecycle

diff --git a/lib/RT/Action/AutoOpen.pm b/lib/RT/Action/AutoOpen.pm
index 22328be..332ec9c 100755
--- a/lib/RT/Action/AutoOpen.pm
+++ b/lib/RT/Action/AutoOpen.pm
@@ -82,7 +82,7 @@ sub Prepare {
     my $self = shift;
 
     my $ticket = $self->TicketObj;
-    my $lifecycle = $ticket->QueueObj->lifecycle;
+    my $lifecycle = $ticket->QueueObj->Lifecycle;
     my $status = $ticket->Status;
 
     my @active = $lifecycle->active;
diff --git a/lib/RT/Action/SetStatus.pm b/lib/RT/Action/SetStatus.pm
index 23dbeff..4950699 100755
--- a/lib/RT/Action/SetStatus.pm
+++ b/lib/RT/Action/SetStatus.pm
@@ -101,7 +101,7 @@ sub Prepare {
     my $self = shift;
 
     my $ticket = $self->TicketObj;
-    my $lifecycle = $ticket->QueueObj->lifecycle;
+    my $lifecycle = $ticket->QueueObj->Lifecycle;
     my $status = $ticket->Status;
 
     my $argument = $self->Argument;
diff --git a/lib/RT/Condition/StatusChange.pm b/lib/RT/Condition/StatusChange.pm
index 394a69d..8de60ff 100755
--- a/lib/RT/Condition/StatusChange.pm
+++ b/lib/RT/Condition/StatusChange.pm
@@ -117,7 +117,7 @@ sub IsApplicable {
         return 0;
     }
 
-    my $lifecycle = $self->TicketObj->QueueObj->lifecycle;
+    my $lifecycle = $self->TicketObj->QueueObj->Lifecycle;
     if ( $new_must_be ) {
         return 0 unless grep lc($new) eq lc($_),
             map {m/^(initial|active|inactive)$/i? $lifecycle->valid(lc $_): $_ }
diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index f329c04..62a4e8c 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -243,7 +243,7 @@ sub RightCategories {
 
 
 
-sub lifecycle {
+sub Lifecycle {
     my $self = shift;
     unless (ref $self && $self->id) { 
         return RT::Lifecycle->load('')
@@ -272,10 +272,7 @@ Returns an array of all ActiveStatuses for this queue
 
 sub ActiveStatusArray {
     my $self = shift;
-
-    my %seen;
-    my @active_statuses = grep !$seen{$_}++, $self->lifecycle->valid('initial', 'active');
-    return @active_statuses;
+    return $self->Lifecycle->valid('initial', 'active');
 }
 
 =head2 InactiveStatusArray
@@ -286,7 +283,7 @@ Returns an array of all InactiveStatuses for this queue
 
 sub InactiveStatusArray {
     my $self = shift;
-    return $self->lifecycle->inactive;
+    return $self->Lifecycle->inactive;
 }
 
 =head2 StatusArray
@@ -297,7 +294,7 @@ Returns an array of all statuses for this queue
 
 sub StatusArray {
     my $self = shift;
-    return $self->lifecycle->valid( @_ );
+    return $self->Lifecycle->valid( @_ );
 }
 
 =head2 IsValidStatus value
@@ -308,7 +305,7 @@ Returns true if value is a valid status.  Otherwise, returns 0.
 
 sub IsValidStatus {
     my $self  = shift;
-    return $self->lifecycle->is_valid( shift );
+    return $self->Lifecycle->is_valid( shift );
 }
 
 =head2 IsActiveStatus value
@@ -319,7 +316,7 @@ Returns true if value is a Active status.  Otherwise, returns 0
 
 sub IsActiveStatus {
     my $self  = shift;
-    return $self->lifecycle->is_valid( shift, 'initial', 'active');
+    return $self->Lifecycle->is_valid( shift, 'initial', 'active');
 }
 
 
@@ -333,7 +330,7 @@ Returns true if value is a Inactive status.  Otherwise, returns 0
 
 sub IsInactiveStatus {
     my $self  = shift;
-    return $self->lifecycle->is_inactive( shift );
+    return $self->Lifecycle->is_inactive( shift );
 }
 
 
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index 6573513..e67af36 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -300,11 +300,11 @@ sub Create {
     }
 
     if ( ! defined $args{'Status'}) {
-        $args{'Status'} = $QueueObj->lifecycle->default_initial();
+        $args{'Status'} = $QueueObj->Lifecycle->default_initial();
     }
 
     unless ( $QueueObj->IsValidStatus( $args{'Status'} )
-            && $QueueObj->lifecycle->is_initial( $args{'Status'} )) {
+            && $QueueObj->Lifecycle->is_initial( $args{'Status'} )) {
         return ( 0, 0,
             $self->loc("Status '[_1]' isn't a valid status for tickets in this queue.",
                 $self->loc($args{'Status'})));
@@ -360,8 +360,8 @@ sub Create {
     #
     # Instead, we check to make sure that it's either an "active" or "inactive" status
     elsif (
-        $QueueObj->lifecycle->is_active($args{'Status'}) ||
-        $QueueObj->lifecycle->is_inactive($args{'Status'})
+        $QueueObj->Lifecycle->is_active($args{'Status'}) ||
+        $QueueObj->Lifecycle->is_inactive($args{'Status'})
 
     ){
         $Started->SetToNow;
@@ -373,7 +373,7 @@ sub Create {
     }
 
     #If the status is an inactive status, set the resolved date
-    elsif ( $QueueObj->lifecycle->is_inactive( $args{'Status'} ) )
+    elsif ( $QueueObj->Lifecycle->is_inactive( $args{'Status'} ) )
     {
         $RT::Logger->debug( "Got a ". $args{'Status'}
             ."(inactive) ticket with undefined resolved date. Setting to now."
@@ -607,7 +607,7 @@ sub Create {
     # TODO: Adding link may fire scrips on other end and those scrips
     # could create transactions on this ticket before 'Create' transaction.
     #
-    # We should implement different lifecycle: record 'Create' transaction,
+    # We should implement different Lifecycle: record 'Create' transaction,
     # create links and only then fire create transaction's scrips.
     #
     # Ideal variant: add all links without firing scrips, record create
@@ -1710,8 +1710,8 @@ sub SetQueue {
     }
 
     my $new_status;
-    my $old_lifecycle = $self->QueueObj->lifecycle;
-    my $new_lifecycle = $NewQueueObj->lifecycle;
+    my $old_lifecycle = $self->QueueObj->Lifecycle;
+    my $new_lifecycle = $NewQueueObj->Lifecycle;
     if ( $old_lifecycle->name ne $new_lifecycle->name ) {
         unless ( $old_lifecycle->has_map( $new_lifecycle ) ) {
             return ( 0, $self->loc("There is no mapping for statuses between these queues. Contact your system administrator.") );
@@ -2654,7 +2654,7 @@ sub _MergeInto {
     }
 
 
-    my $default_inactive = $self->QueueObj->lifecycle->default_inactive;
+    my $default_inactive = $self->QueueObj->Lifecycle->default_inactive;
     if ( $default_inactive ne $self->__Value('Status') ) {
         my ( $status_val, $status_msg )
             = $self->__Set( Field => 'Status', Value => $default_inactive );
@@ -3089,7 +3089,7 @@ sub SetStatus {
     $args{SetStarted} = 1 unless exists $args{SetStarted};
 
 
-    my $lifecycle = $self->QueueObj->lifecycle;
+    my $lifecycle = $self->QueueObj->Lifecycle;
 
     my $new = $args{'Status'};
     unless ( $lifecycle->is_valid( $new ) ) {
diff --git a/share/html/Elements/QueueSummaryByLifecycle b/share/html/Elements/QueueSummaryByLifecycle
index 49ef0a7..45e23a3 100644
--- a/share/html/Elements/QueueSummaryByLifecycle
+++ b/share/html/Elements/QueueSummaryByLifecycle
@@ -115,7 +115,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
     {  id          => $_->Id,
        Name        => $_->Name,
        Description => $_->Description,
-       Lifecycle   => $_->lifecycle->name,
+       Lifecycle   => $_->Lifecycle->name,
     }
 } grep $_, @queues;
 
diff --git a/share/html/Elements/QueueSummaryByStatus b/share/html/Elements/QueueSummaryByStatus
index 58dce73..37cad16 100644
--- a/share/html/Elements/QueueSummaryByStatus
+++ b/share/html/Elements/QueueSummaryByStatus
@@ -113,7 +113,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
     {  id          => $_->Id,
        Name        => $_->Name,
        Description => $_->Description,
-       Lifecycle   => $_->lifecycle->name,
+       Lifecycle   => $_->Lifecycle->name,
     }
 } grep $_, @queues;
 
diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index 1178412..088456d 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -61,7 +61,7 @@
 my @status;
 if ( $TicketObj ) {
     my $current = $TicketObj->Status;
-    my $lifecycle = $TicketObj->QueueObj->lifecycle;
+    my $lifecycle = $TicketObj->QueueObj->Lifecycle;
 
     my %has = ();
     foreach my $next ( $lifecycle->transitions( $current ) ) {
@@ -72,10 +72,10 @@ if ( $TicketObj ) {
     }
 }
 elsif ( $QueueObj ) {
-    @status = $QueueObj->lifecycle->valid;
+    @status = $QueueObj->Lifecycle->valid;
 }
 else {
-    @status = RT::Queue->lifecycle->valid;
+    @status = RT::Queue->Lifecycle->valid;
 }
 </%INIT>
 <%ARGS>
diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index 95c34e1..433142a 100755
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -370,7 +370,7 @@ if ( $request_path !~ qr{^/SelfService/} ) {
 
             if ( $can{'ModifyTicket'} ) {
                 my $current   = $obj->Status;
-                my $lifecycle = $obj->QueueObj->lifecycle;
+                my $lifecycle = $obj->QueueObj->Lifecycle;
                 my $i         = 1;
 
                 foreach my $info ( $lifecycle->actions($current) ) {
diff --git a/t/lifecycles/basics.t b/t/lifecycles/basics.t
index 1448d7b..ba963ba 100644
--- a/t/lifecycles/basics.t
+++ b/t/lifecycles/basics.t
@@ -20,7 +20,7 @@ my $tstatus = sub {
 
 diag "check basic API";
 {
-    my $schema = $general->lifecycle;
+    my $schema = $general->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
     is $schema->name, 'default', "it's a default schema";
     is join(', ', sort $schema->valid),
@@ -43,7 +43,7 @@ diag "check status input on create";
 
     my $valid = 1;
     foreach ( @form_values ) {
-        next if $general->lifecycle->is_valid($_);
+        next if $general->Lifecycle->is_valid($_);
         $valid = 0;
         diag("$_ doesn't appear to be a valid status, but it was in the form");
     }
diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index a107dca..afe45ce 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -28,11 +28,11 @@ ok $m->login, 'logged in';
 
 diag "check basic API";
 {
-    my $schema = $general->lifecycle;
+    my $schema = $general->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
     is $schema->name, 'default', "it's a default schema";
 
-    $schema = $delivery->lifecycle;
+    $schema = $delivery->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
     is $schema->name, 'delivery', "it's a delivery schema";
 }

commit cb59cd48a1b87fe5071202f86ef253bd24d15193
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 5 07:48:53 2010 +0300

    is_valid -> IsValid

diff --git a/lib/RT/Action/SetStatus.pm b/lib/RT/Action/SetStatus.pm
index 4950699..cfc8d35 100755
--- a/lib/RT/Action/SetStatus.pm
+++ b/lib/RT/Action/SetStatus.pm
@@ -119,7 +119,7 @@ sub Prepare {
             return 1;
         }
     }
-    elsif ( $lifecycle->is_valid( $argument ) ) {
+    elsif ( $lifecycle->IsValid( $argument ) ) {
         unless ( $lifecycle->is_transition( $status => $argument ) ) {
             $RT::Logger->warning("Transition '$status -> $argument' is not valid");
             return 1;
diff --git a/lib/RT/Condition/StatusChange.pm b/lib/RT/Condition/StatusChange.pm
index 8de60ff..95aeaaa 100755
--- a/lib/RT/Condition/StatusChange.pm
+++ b/lib/RT/Condition/StatusChange.pm
@@ -113,7 +113,7 @@ sub IsApplicable {
     }
     else {
         $RT::Logger->error("Argument '$argument' is incorrect.")
-            unless RT::Lifecycle->load('')->is_valid( $argument );
+            unless RT::Lifecycle->load('')->IsValid( $argument );
         return 0;
     }
 
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index d611ba9..a3354e4 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -196,7 +196,7 @@ sub valid {
     return @res;
 }
 
-=head3 is_valid
+=head3 IsValid
 
 Takes a status and returns true if value is a valid status for the current
 lifecycle. Otherwise, returns false.
@@ -205,13 +205,13 @@ Takes optional list of status types after the status, so it's possible check
 validity in particular sets, for example:
 
     # returns true if status is valid and from initial or active set
-    $lifecycle->is_valid('some_status', 'initial', 'active');
+    $lifecycle->IsValid('some_status', 'initial', 'active');
 
 See also </valid>.
 
 =cut
 
-sub is_valid {
+sub IsValid {
     my $self  = shift;
     my $value = lc shift;
     return 1 if grep lc($_) eq $value, $self->valid( @_ );
@@ -700,7 +700,7 @@ sub from_set {
     my $self = shift;
     my $status = shift;
     foreach my $set ( qw(initial active inactive) ) {
-        return $set if $self->is_valid( $status, $set );
+        return $set if $self->IsValid( $status, $set );
     }
     return '';
 }
diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index 62a4e8c..5602095 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -305,7 +305,7 @@ Returns true if value is a valid status.  Otherwise, returns 0.
 
 sub IsValidStatus {
     my $self  = shift;
-    return $self->Lifecycle->is_valid( shift );
+    return $self->Lifecycle->IsValid( shift );
 }
 
 =head2 IsActiveStatus value
@@ -316,7 +316,7 @@ Returns true if value is a Active status.  Otherwise, returns 0
 
 sub IsActiveStatus {
     my $self  = shift;
-    return $self->Lifecycle->is_valid( shift, 'initial', 'active');
+    return $self->Lifecycle->IsValid( shift, 'initial', 'active');
 }
 
 
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index e67af36..3062227 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -3092,7 +3092,7 @@ sub SetStatus {
     my $lifecycle = $self->QueueObj->Lifecycle;
 
     my $new = $args{'Status'};
-    unless ( $lifecycle->is_valid( $new ) ) {
+    unless ( $lifecycle->IsValid( $new ) ) {
         return (0, $self->loc("Status '[_1]' isn't a valid status for tickets in this queue.", $self->loc($new)));
     }
 
diff --git a/share/html/Elements/QueueSummaryByLifecycle b/share/html/Elements/QueueSummaryByLifecycle
index 45e23a3..5c46719 100644
--- a/share/html/Elements/QueueSummaryByLifecycle
+++ b/share/html/Elements/QueueSummaryByLifecycle
@@ -47,7 +47,7 @@
 %# END BPS TAGGED BLOCK }}}
 <%perl>
     foreach my $lifecycle ( map $lifecycle{$_}, sort keys %lifecycle ) {
-    my @cur_statuses = grep $lifecycle->is_valid($_), @statuses;
+    my @cur_statuses = grep $lifecycle->IsValid($_), @statuses;
     next unless @cur_statuses;
 </%perl>
 
diff --git a/share/html/Elements/QueueSummaryByStatus b/share/html/Elements/QueueSummaryByStatus
index 37cad16..8494973 100644
--- a/share/html/Elements/QueueSummaryByStatus
+++ b/share/html/Elements/QueueSummaryByStatus
@@ -62,7 +62,7 @@ for my $queue (@queues) {
     $name =~ s/'/\\'/g;
     my $queue_cond = "Queue = '$name' AND ";
     my $lifecycle = $lifecycle{ lc $queue->{'Lifecycle'} };
-    my $all_q = $queue_cond . '(' . join( " OR ", map "Status = '$_'", grep $lifecycle->is_valid($_), @statuses ) . ')';
+    my $all_q = $queue_cond . '(' . join( " OR ", map "Status = '$_'", grep $lifecycle->IsValid($_), @statuses ) . ')';
 </%PERL>
 <tr class="<% $i%2 ? 'oddline' : 'evenline'%>" >
 
@@ -72,7 +72,7 @@ for my $queue (@queues) {
 
 <%perl>
    for my $status (@statuses) {
-   if ( $lifecycle->is_valid( $status ) ) {
+   if ( $lifecycle->IsValid( $status ) ) {
 </%perl>
 <td align="right">
     <a href="<% RT->Config->Get('WebPath') %>/Search/Results.html?Query=<% $queue_cond ."Status = '$status'" |u,n %>"><% $data->{$queue->{id}}->{$status} || '-'%></a>
diff --git a/t/lifecycles/basics.t b/t/lifecycles/basics.t
index ba963ba..929cb72 100644
--- a/t/lifecycles/basics.t
+++ b/t/lifecycles/basics.t
@@ -43,7 +43,7 @@ diag "check status input on create";
 
     my $valid = 1;
     foreach ( @form_values ) {
-        next if $general->Lifecycle->is_valid($_);
+        next if $general->Lifecycle->IsValid($_);
         $valid = 0;
         diag("$_ doesn't appear to be a valid status, but it was in the form");
     }

commit 900099bec62fc167062506054bba9a1386ab2da7
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 5 09:34:10 2010 +0300

    camel case RT::Lifecycle->IsInitial

diff --git a/lib/RT/Action/AutoOpen.pm b/lib/RT/Action/AutoOpen.pm
index 332ec9c..08394ed 100755
--- a/lib/RT/Action/AutoOpen.pm
+++ b/lib/RT/Action/AutoOpen.pm
@@ -94,7 +94,7 @@ sub Prepare {
 
     # no change if the ticket is in initial status and the message is a mail
     # from a requestor
-    return 1 if $lifecycle->is_initial($status) && $self->TransactionObj->IsInbound;
+    return 1 if $lifecycle->IsInitial($status) && $self->TransactionObj->IsInbound;
 
     if ( my $msg = $self->TransactionObj->Message->First ) {
         return 1 if ($msg->GetHeader('RT-Control') || '') =~ /\bno-autoopen\b/i;
diff --git a/lib/RT/Action/SetStatus.pm b/lib/RT/Action/SetStatus.pm
index cfc8d35..ee11c6d 100755
--- a/lib/RT/Action/SetStatus.pm
+++ b/lib/RT/Action/SetStatus.pm
@@ -112,7 +112,7 @@ sub Prepare {
 
     my $next = '';
     if ( $argument =~ /^(initial|active|inactive)$/i ) {
-        my $method = 'is_'. lc $argument;
+        my $method = 'Is'. ucfirst lc $argument;
         ($next) = grep $lifecycle->$method($_), $lifecycle->transitions($status);
         unless ( $next ) {
             $RT::Logger->info("No transition from '$status' to $argument set");
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index a3354e4..ea54af8 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -218,25 +218,25 @@ sub IsValid {
     return 0;
 }
 
-=head3 initial
+=head3 Initial
 
 Returns an array of all initial statuses for the current lifecycle.
 
 =cut
 
-sub initial {
+sub Initial {
     my $self = shift;
     return $self->valid('initial');
 }
 
-=head3 is_initial
+=head3 IsInitial
 
 Takes a status and returns true if value is a valid initial status.
 Otherwise, returns false.
 
 =cut
 
-sub is_initial {
+sub IsInitial {
     my $self  = shift;
     my $value = lc shift;
     return 1 if grep lc($_) eq $value, $self->valid('initial');
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index 3062227..94e6dc4 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -304,7 +304,7 @@ sub Create {
     }
 
     unless ( $QueueObj->IsValidStatus( $args{'Status'} )
-            && $QueueObj->Lifecycle->is_initial( $args{'Status'} )) {
+            && $QueueObj->Lifecycle->IsInitial( $args{'Status'} )) {
         return ( 0, 0,
             $self->loc("Status '[_1]' isn't a valid status for tickets in this queue.",
                 $self->loc($args{'Status'})));
@@ -1745,7 +1745,7 @@ sub SetQueue {
 
         #If we're changing the status from initial in old to not intial in new,
         # record that we've started
-        if ( $old_lifecycle->is_initial($old_status) && !$new_lifecycle->is_initial($new_status)  && $clone->StartedObj->Unix == 0 ) {
+        if ( $old_lifecycle->IsInitial($old_status) && !$new_lifecycle->IsInitial($new_status)  && $clone->StartedObj->Unix == 0 ) {
             #Set the Started time to "now"
             $clone->_Set(
                 Field             => 'Started',
@@ -3117,7 +3117,7 @@ sub SetStatus {
     $raw_started->Set(Format => 'ISO', Value => $self->__Value('Started'));
 
     #If we're changing the status from new, record that we've started
-    if ( $args{SetStarted} && $lifecycle->is_initial($old) && !$lifecycle->is_initial($new) && !$raw_started->Unix) {
+    if ( $args{SetStarted} && $lifecycle->IsInitial($old) && !$lifecycle->IsInitial($new) && !$raw_started->Unix) {
         #Set the Started time to "now"
         $self->_Set(
             Field             => 'Started',

commit ecea142a4f695bf99a14d3af9c508d5590a1db61
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 03:02:58 2010 +0300

    more camel casing for lifecycles

diff --git a/lib/RT/Action/AutoOpen.pm b/lib/RT/Action/AutoOpen.pm
index 08394ed..7a84641 100755
--- a/lib/RT/Action/AutoOpen.pm
+++ b/lib/RT/Action/AutoOpen.pm
@@ -85,7 +85,7 @@ sub Prepare {
     my $lifecycle = $ticket->QueueObj->Lifecycle;
     my $status = $ticket->Status;
 
-    my @active = $lifecycle->active;
+    my @active = $lifecycle->Active;
     # no change if no active statuses in the lifecycle
     return 1 unless @active;
 
@@ -100,7 +100,7 @@ sub Prepare {
         return 1 if ($msg->GetHeader('RT-Control') || '') =~ /\bno-autoopen\b/i;
     }
 
-    my ($next) = grep $lifecycle->is_active($_), $lifecycle->transitions($status);
+    my ($next) = grep $lifecycle->IsActive($_), $lifecycle->Transitions($status);
 
     $self->{'set_status_to'} = $next;
 
diff --git a/lib/RT/Action/SetStatus.pm b/lib/RT/Action/SetStatus.pm
index ee11c6d..dd39393 100755
--- a/lib/RT/Action/SetStatus.pm
+++ b/lib/RT/Action/SetStatus.pm
@@ -113,14 +113,14 @@ sub Prepare {
     my $next = '';
     if ( $argument =~ /^(initial|active|inactive)$/i ) {
         my $method = 'Is'. ucfirst lc $argument;
-        ($next) = grep $lifecycle->$method($_), $lifecycle->transitions($status);
+        ($next) = grep $lifecycle->$method($_), $lifecycle->Transitions($status);
         unless ( $next ) {
             $RT::Logger->info("No transition from '$status' to $argument set");
             return 1;
         }
     }
     elsif ( $lifecycle->IsValid( $argument ) ) {
-        unless ( $lifecycle->is_transition( $status => $argument ) ) {
+        unless ( $lifecycle->IsTransition( $status => $argument ) ) {
             $RT::Logger->warning("Transition '$status -> $argument' is not valid");
             return 1;
         }
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index ea54af8..a6e49f3 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -250,31 +250,31 @@ Returns the "default" initial status for this lifecycle
 
 =cut
 
-sub default_initial {
+sub DefaultInitial {
     my $self = shift;
     return $self->{data}->{default_initial};
 }
 
 
-=head3 active
+=head3 Active
 
 Returns an array of all active statuses for this lifecycle.
 
 =cut
 
-sub active {
+sub Active {
     my $self = shift;
     return $self->valid('active');
 }
 
-=head3 is_active
+=head3 IsActive
 
 Takes a value and returns true if value is a valid active status.
 Otherwise, returns false.
 
 =cut
 
-sub is_active {
+sub IsActive {
     my $self  = shift;
     my $value = lc shift;
     return 1 if grep lc($_) eq $value, $self->valid('active');
@@ -287,7 +287,7 @@ Returns an array of all inactive statuses for this lifecycle.
 
 =cut
 
-sub inactive {
+sub Inactive {
     my $self = shift;
     return $self->valid('inactive');
 }
@@ -299,7 +299,7 @@ Otherwise, returns false.
 
 =cut
 
-sub is_inactive {
+sub IsInactive {
     my $self  = shift;
     my $value = lc shift;
     return 1 if grep lc($_) eq $value, $self->valid('inactive');
@@ -331,7 +331,7 @@ in the following format:
 
 =cut
 
-sub transitions {
+sub Transitions {
     my $self = shift;
     my $status = shift;
     if ( $status ) {
@@ -341,18 +341,18 @@ sub transitions {
     }
 }
 
-=head1 is_transition
+=head1 IsTransition
 
 Takes two statuses (from -> to) and returns true if it's valid
 transition and false otherwise.
 
 =cut
 
-sub is_transition {
+sub IsTransition {
     my $self = shift;
     my $from = shift or return 0;
     my $to   = shift or return 0;
-    return 1 if grep lc($_) eq lc($to), $self->transitions($from);
+    return 1 if grep lc($_) eq lc($to), $self->Transitions($from);
     return 0;
 }
 
diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index 5602095..6e1b987 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -283,7 +283,7 @@ Returns an array of all InactiveStatuses for this queue
 
 sub InactiveStatusArray {
     my $self = shift;
-    return $self->Lifecycle->inactive;
+    return $self->Lifecycle->Inactive;
 }
 
 =head2 StatusArray
@@ -330,7 +330,7 @@ Returns true if value is a Inactive status.  Otherwise, returns 0
 
 sub IsInactiveStatus {
     my $self  = shift;
-    return $self->Lifecycle->is_inactive( shift );
+    return $self->Lifecycle->IsInactive( shift );
 }
 
 
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index 94e6dc4..45b6ba9 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -300,7 +300,7 @@ sub Create {
     }
 
     if ( ! defined $args{'Status'}) {
-        $args{'Status'} = $QueueObj->Lifecycle->default_initial();
+        $args{'Status'} = $QueueObj->Lifecycle->DefaultInitial();
     }
 
     unless ( $QueueObj->IsValidStatus( $args{'Status'} )
@@ -360,8 +360,8 @@ sub Create {
     #
     # Instead, we check to make sure that it's either an "active" or "inactive" status
     elsif (
-        $QueueObj->Lifecycle->is_active($args{'Status'}) ||
-        $QueueObj->Lifecycle->is_inactive($args{'Status'})
+        $QueueObj->Lifecycle->IsActive($args{'Status'}) ||
+        $QueueObj->Lifecycle->IsInactive($args{'Status'})
 
     ){
         $Started->SetToNow;
@@ -373,7 +373,7 @@ sub Create {
     }
 
     #If the status is an inactive status, set the resolved date
-    elsif ( $QueueObj->Lifecycle->is_inactive( $args{'Status'} ) )
+    elsif ( $QueueObj->Lifecycle->IsInactive( $args{'Status'} ) )
     {
         $RT::Logger->debug( "Got a ". $args{'Status'}
             ."(inactive) ticket with undefined resolved date. Setting to now."
@@ -1756,7 +1756,7 @@ sub SetQueue {
 
         #When we close a ticket, set the 'Resolved' attribute to now.
         # It's misnamed, but that's just historical.
-        if ( $new_lifecycle->is_inactive($new_status) ) {
+        if ( $new_lifecycle->IsInactive($new_status) ) {
             $clone->_Set(
                 Field             => 'Resolved',
                 Value             => $now->ISO,
@@ -3097,7 +3097,7 @@ sub SetStatus {
     }
 
     my $old = $self->__Value('Status');
-    unless ( $lifecycle->is_transition( $old => $new ) ) {
+    unless ( $lifecycle->IsTransition( $old => $new ) ) {
         return (0, $self->loc("You can't change status from '[_1]' to '[_2]'.", $self->loc($old), $self->loc($new)));
     }
 
@@ -3106,7 +3106,7 @@ sub SetStatus {
         return ( 0, $self->loc('Permission Denied') );
     }
 
-    if ( !$args{Force} && $lifecycle->is_inactive( $new ) && $self->HasUnresolvedDependencies) {
+    if ( !$args{Force} && $lifecycle->IsInactive( $new ) && $self->HasUnresolvedDependencies) {
         return (0, $self->loc('That ticket has unresolved dependencies'));
     }
 
@@ -3128,7 +3128,7 @@ sub SetStatus {
 
     #When we close a ticket, set the 'Resolved' attribute to now.
     # It's misnamed, but that's just historical.
-    if ( $lifecycle->is_inactive($new) ) {
+    if ( $lifecycle->IsInactive($new) ) {
         $self->_Set(
             Field             => 'Resolved',
             Value             => $now->ISO,
diff --git a/share/html/Elements/QueueSummaryByLifecycle b/share/html/Elements/QueueSummaryByLifecycle
index 5c46719..a4d4207 100644
--- a/share/html/Elements/QueueSummaryByLifecycle
+++ b/share/html/Elements/QueueSummaryByLifecycle
@@ -130,7 +130,7 @@ unless (@statuses) {
     my %seen;
     foreach my $set ( 'initial', 'active' ) {
         foreach my $lifecycle ( map $lifecycle{$_}, sort keys %lifecycle ) {
-            push @statuses, grep !$seen{ lc $_ }++, $lifecycle->$set();
+            push @statuses, grep !$seen{ lc $_ }++, $lifecycle->valid($set);
         }
     }
 }
diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index 088456d..9e9a125 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -64,7 +64,7 @@ if ( $TicketObj ) {
     my $lifecycle = $TicketObj->QueueObj->Lifecycle;
 
     my %has = ();
-    foreach my $next ( $lifecycle->transitions( $current ) ) {
+    foreach my $next ( $lifecycle->Transitions( $current ) ) {
         my $check = $lifecycle->check_right( $current => $next );
         $has{ $check } = $TicketObj->CurrentUserHasRight( $check )
             unless exists $has{ $check };
diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index 433142a..cb03de3 100755
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -373,16 +373,16 @@ if ( $request_path !~ qr{^/SelfService/} ) {
                 my $lifecycle = $obj->QueueObj->Lifecycle;
                 my $i         = 1;
 
-                foreach my $info ( $lifecycle->actions($current) ) {
+                foreach my $info ( $lifecycle->Actions($current) ) {
                     my $next = $info->{'to'};
-                    next unless $lifecycle->is_transition( $current => $next );
+                    next unless $lifecycle->IsTransition( $current => $next );
 
-                    my $check = $lifecycle->check_right( $current => $next );
+                    my $check = $lifecycle->CheckRight( $current => $next );
                     $can{$check} = $obj->CurrentUserHasRight($check) unless exists $can{$check};
                     next unless $can{$check};
 
 
-                   my $action = $info->{'update'} || '';
+                    my $action = $info->{'update'} || '';
 
 
                     my $url = '/Ticket/';

commit ce4db52390d40ceffa65f073f4e0199947dbc054
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 03:40:33 2010 +0300

    Lifecycle->load -> Lifecycle->Load

diff --git a/lib/RT/Condition/StatusChange.pm b/lib/RT/Condition/StatusChange.pm
index 95aeaaa..4e6de7c 100755
--- a/lib/RT/Condition/StatusChange.pm
+++ b/lib/RT/Condition/StatusChange.pm
@@ -113,7 +113,7 @@ sub IsApplicable {
     }
     else {
         $RT::Logger->error("Argument '$argument' is incorrect.")
-            unless RT::Lifecycle->load('')->IsValid( $argument );
+            unless RT::Lifecycle->Load('')->IsValid( $argument );
         return 0;
     }
 
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index a6e49f3..b7d6dd9 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -51,8 +51,6 @@ use warnings;
 
 package RT::Lifecycle;
 
-sub loc { return RT->SystemUser->loc( @_ ) }
-
 our %LIFECYCLES;
 our %LIFECYCLES_CACHE;
 __PACKAGE__->register_rights;
@@ -120,21 +118,21 @@ sub new {
     return $self;
 }
 
-=head2 load
+=head2 Load
 
 Takes a name of the lifecycle and loads it. If name is empty or undefined then
 loads the global lifecycle with statuses from all named lifecycles.
 
 Can be called as class method, returns a new object, for example:
 
-    my $lifecycle = RT::Lifecycle->load('default');
+    my $lifecycle = RT::Lifecycle->Load('default');
 
 =cut
 
-sub load {
+sub Load {
     my $self = shift;
     my $name = shift || '';
-    return $self->new->load( $name, @_ )
+    return $self->new->Load( $name, @_ )
         unless ref $self;
 
     return unless exists $LIFECYCLES_CACHE{ $name };
@@ -631,7 +629,7 @@ sub _store_lifecycles {
         content => \%LIFECYCLES,
     );
     $self->fill_cache;
-    $self->load( $name );
+    $self->Load( $name );
     return ($status, loc("Couldn't store lifecycle")) unless $status;
     return 1;
 }
@@ -708,14 +706,14 @@ sub from_set {
 sub map {
     my $from = shift;
     my $to = shift;
-    $to = RT::Lifecycle->load( $to ) unless ref $to;
+    $to = RT::Lifecycle->Load( $to ) unless ref $to;
     return $LIFECYCLES{'__maps__'}{ $from->name .' -> '. $to->name } || {};
 }
 
 sub set_map {
     my $self = shift;
     my $to = shift;
-    $to = RT::Lifecycle->load( $to ) unless ref $to;
+    $to = RT::Lifecycle->Load( $to ) unless ref $to;
     my %map = @_;
     $map{ lc $_ } = delete $map{ $_ } foreach keys %map;
 
@@ -750,7 +748,7 @@ sub no_maps {
         foreach my $to ( @list ) {
             next if $from eq $to;
             push @res, $from, $to
-                unless RT::Lifecycle->load( $from )->has_map( $to );
+                unless RT::Lifecycle->Load( $from )->has_map( $to );
         }
     }
     return @res;
@@ -764,4 +762,6 @@ sub queues {
     return $queues;
 }
 
+sub loc { return RT->SystemUser->loc( @_ ) }
+
 1;
diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index 6e1b987..71d8667 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -246,7 +246,7 @@ sub RightCategories {
 sub Lifecycle {
     my $self = shift;
     unless (ref $self && $self->id) { 
-        return RT::Lifecycle->load('')
+        return RT::Lifecycle->Load('')
     }
 
     my $name = '';
@@ -259,7 +259,7 @@ sub Lifecycle {
         $name = 'default';
     }
 
-    my $res = RT::Lifecycle->load( $name );
+    my $res = RT::Lifecycle->Load( $name );
     $RT::Logger->error("Lifecycle '$name' for queue '".$self->Name."' doesn't exist") unless $res;
     return $res;
 }
diff --git a/share/html/Elements/QueueSummaryByLifecycle b/share/html/Elements/QueueSummaryByLifecycle
index a4d4207..96c7a23 100644
--- a/share/html/Elements/QueueSummaryByLifecycle
+++ b/share/html/Elements/QueueSummaryByLifecycle
@@ -122,7 +122,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
 my %lifecycle;
 
 for my $queue (@queues) {
-    my $cycle = RT::Lifecycle->load( $queue->{'Lifecycle'} );
+    my $cycle = RT::Lifecycle->Load( $queue->{'Lifecycle'} );
     $lifecycle{ lc $cycle->name } = $cycle;
 }
 
diff --git a/share/html/Elements/QueueSummaryByStatus b/share/html/Elements/QueueSummaryByStatus
index 8494973..d2b2e73 100644
--- a/share/html/Elements/QueueSummaryByStatus
+++ b/share/html/Elements/QueueSummaryByStatus
@@ -121,7 +121,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
 my %lifecycle;
 
 for my $queue (@queues) {
-    my $cycle = RT::Lifecycle->load( $queue->{'Lifecycle'} );
+    my $cycle = RT::Lifecycle->Load( $queue->{'Lifecycle'} );
     $lifecycle{ lc $cycle->name } = $cycle;
 }
 

commit 0bcabe7b03265322313c1257048225bc734ed404
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 04:42:35 2010 +0300

    more camel casing lifecycles code

diff --git a/lib/RT/Condition/StatusChange.pm b/lib/RT/Condition/StatusChange.pm
index 4e6de7c..8c0637f 100755
--- a/lib/RT/Condition/StatusChange.pm
+++ b/lib/RT/Condition/StatusChange.pm
@@ -120,7 +120,7 @@ sub IsApplicable {
     my $lifecycle = $self->TicketObj->QueueObj->Lifecycle;
     if ( $new_must_be ) {
         return 0 unless grep lc($new) eq lc($_),
-            map {m/^(initial|active|inactive)$/i? $lifecycle->valid(lc $_): $_ }
+            map {m/^(initial|active|inactive)$/i? $lifecycle->Valid(lc $_): $_ }
             grep defined && length,
             map { s/^\s+//; s/\s+$//; $_ }
             split /,/, $new_must_be;
@@ -128,7 +128,7 @@ sub IsApplicable {
     if ( $old_must_be ) {
         my $old = lc($txn->OldValue || '');
         return 0 unless grep $old eq lc($_),
-            map {m/^(initial|active|inactive)$/i? $lifecycle->valid(lc $_): $_ }
+            map {m/^(initial|active|inactive)$/i? $lifecycle->Valid(lc $_): $_ }
             grep defined && length,
             map { s/^\s+//; s/\s+$//; $_ }
             split /,/, $old_must_be;
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index b7d6dd9..18ad629 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -143,13 +143,13 @@ sub Load {
     return $self;
 }
 
-=head2 list
+=head2 List
 
 Returns sorted list of the lifecycles' names.
 
 =cut
 
-sub list {
+sub List {
     my $self = shift;
 
     $self->fill_cache unless keys %LIFECYCLES_CACHE;
@@ -157,19 +157,19 @@ sub list {
     return sort grep length && $_ ne '__maps__', keys %LIFECYCLES_CACHE;
 }
 
-=head2 name
+=head2 Name
 
 Returns name of the laoded lifecycle.
 
 =cut
 
-sub name { return $_[0]->{'name'} }
+sub Name { return $_[0]->{'name'} }
 
 =head2 Getting statuses and validating.
 
 Methods to get statuses in different sets or validating them.
 
-=head3 valid
+=head3 Valid
 
 Returns an array of all valid statuses for the current lifecycle.
 Statuses are not sorted alphabetically, instead initial goes first,
@@ -178,11 +178,11 @@ then active and then inactive.
 Takes optional list of status types, from 'initial', 'active' or
 'inactive'. For example:
 
-    $lifecycle->valid('initial', 'active');
+    $lifecycle->Valid('initial', 'active');
 
 =cut
 
-sub valid {
+sub Valid {
     my $self = shift;
     my @types = @_;
     unless ( @types ) {
@@ -212,7 +212,7 @@ See also </valid>.
 sub IsValid {
     my $self  = shift;
     my $value = lc shift;
-    return 1 if grep lc($_) eq $value, $self->valid( @_ );
+    return 1 if grep lc($_) eq $value, $self->Valid( @_ );
     return 0;
 }
 
@@ -224,7 +224,7 @@ Returns an array of all initial statuses for the current lifecycle.
 
 sub Initial {
     my $self = shift;
-    return $self->valid('initial');
+    return $self->Valid('initial');
 }
 
 =head3 IsInitial
@@ -237,7 +237,7 @@ Otherwise, returns false.
 sub IsInitial {
     my $self  = shift;
     my $value = lc shift;
-    return 1 if grep lc($_) eq $value, $self->valid('initial');
+    return 1 if grep lc($_) eq $value, $self->Valid('initial');
     return 0;
 }
 
@@ -262,7 +262,7 @@ Returns an array of all active statuses for this lifecycle.
 
 sub Active {
     my $self = shift;
-    return $self->valid('active');
+    return $self->Valid('active');
 }
 
 =head3 IsActive
@@ -275,7 +275,7 @@ Otherwise, returns false.
 sub IsActive {
     my $self  = shift;
     my $value = lc shift;
-    return 1 if grep lc($_) eq $value, $self->valid('active');
+    return 1 if grep lc($_) eq $value, $self->Valid('active');
     return 0;
 }
 
@@ -287,7 +287,7 @@ Returns an array of all inactive statuses for this lifecycle.
 
 sub Inactive {
     my $self = shift;
-    return $self->valid('inactive');
+    return $self->Valid('inactive');
 }
 
 =head3 is_inactive
@@ -300,7 +300,7 @@ Otherwise, returns false.
 sub IsInactive {
     my $self  = shift;
     my $value = lc shift;
-    return 1 if grep lc($_) eq $value, $self->valid('inactive');
+    return 1 if grep lc($_) eq $value, $self->Valid('inactive');
     return 0;
 }
 
@@ -498,7 +498,7 @@ sub set_statuses {
         @_
     );
 
-    my $name = $self->name or return (0, loc("Lifecycle is not loaded"));
+    my $name = $self->Name or return (0, loc("Lifecycle is not loaded"));
 
     my ($status, $msg) = $self->_set_statuses( %args, name => $name );
     return ($status, $msg) unless $status;
@@ -516,7 +516,7 @@ sub set_transitions {
     my $self = shift;
     my %args = @_;
 
-    my $name = $self->name or return (0, loc("Lifecycle is not loaded"));
+    my $name = $self->Name or return (0, loc("Lifecycle is not loaded"));
 
     my ($status, $msg) = $self->_set_transitions(
         transitions => \%args, name => $name
@@ -533,7 +533,7 @@ sub set_actions {
     my $self = shift;
     my %args = @_;
 
-    my $name = $self->name or return (0, loc("Lifecycle is not loaded"));
+    my $name = $self->Name or return (0, loc("Lifecycle is not loaded"));
 
     my ($status, $msg) = $self->_set_actions(
         actions => \%args, name => $name
@@ -707,7 +707,7 @@ sub map {
     my $from = shift;
     my $to = shift;
     $to = RT::Lifecycle->Load( $to ) unless ref $to;
-    return $LIFECYCLES{'__maps__'}{ $from->name .' -> '. $to->name } || {};
+    return $LIFECYCLES{'__maps__'}{ $from->Name .' -> '. $to->Name } || {};
 }
 
 sub set_map {
@@ -718,15 +718,15 @@ sub set_map {
     $map{ lc $_ } = delete $map{ $_ } foreach keys %map;
 
     return (0, loc("Lifecycle is not loaded"))
-        unless $self->name;
+        unless $self->Name;
 
     return (0, loc("Lifecycle is not loaded"))
-        unless $to->name;
+        unless $to->Name;
 
 
-    $LIFECYCLES{'__maps__'}{ $self->name .' -> '. $to->name } = \%map;
+    $LIFECYCLES{'__maps__'}{ $self->Name .' -> '. $to->Name } = \%map;
 
-    my ($status, $msg) = $self->_store_lifecycles( $self->name );
+    my ($status, $msg) = $self->_store_lifecycles( $self->Name );
     return ($status, $msg) unless $status;
 
     return (1, loc('Updated lifecycle with actions data'));
@@ -742,7 +742,7 @@ sub has_map {
 
 sub no_maps {
     my $self = shift;
-    my @list = $self->list;
+    my @list = $self->List;
     my @res;
     foreach my $from ( @list ) {
         foreach my $to ( @list ) {
@@ -758,7 +758,7 @@ sub queues {
     my $self = shift;
     require RT::Queues;
     my $queues = RT::Queues->new( RT->SystemUser );
-    $queues->limit( column => 'lifecycle', value => $self->name );
+    $queues->limit( column => 'lifecycle', value => $self->Name );
     return $queues;
 }
 
diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index 71d8667..d662636 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -272,7 +272,7 @@ Returns an array of all ActiveStatuses for this queue
 
 sub ActiveStatusArray {
     my $self = shift;
-    return $self->Lifecycle->valid('initial', 'active');
+    return $self->Lifecycle->Valid('initial', 'active');
 }
 
 =head2 InactiveStatusArray
@@ -294,7 +294,7 @@ Returns an array of all statuses for this queue
 
 sub StatusArray {
     my $self = shift;
-    return $self->Lifecycle->valid( @_ );
+    return $self->Lifecycle->Valid( @_ );
 }
 
 =head2 IsValidStatus value
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index 45b6ba9..fd05ff3 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -1712,7 +1712,7 @@ sub SetQueue {
     my $new_status;
     my $old_lifecycle = $self->QueueObj->Lifecycle;
     my $new_lifecycle = $NewQueueObj->Lifecycle;
-    if ( $old_lifecycle->name ne $new_lifecycle->name ) {
+    if ( $old_lifecycle->Name ne $new_lifecycle->Name ) {
         unless ( $old_lifecycle->has_map( $new_lifecycle ) ) {
             return ( 0, $self->loc("There is no mapping for statuses between these queues. Contact your system administrator.") );
         }
diff --git a/share/html/Elements/QueueSummaryByLifecycle b/share/html/Elements/QueueSummaryByLifecycle
index 96c7a23..b36d025 100644
--- a/share/html/Elements/QueueSummaryByLifecycle
+++ b/share/html/Elements/QueueSummaryByLifecycle
@@ -63,7 +63,7 @@
 <%PERL>
 my $i = 0;
 for my $queue (@queues) {
-    next if lc($queue->{Lifecycle} || '') ne lc $lifecycle->name;
+    next if lc($queue->{Lifecycle} || '') ne lc $lifecycle->Name;
 
     $i++;
     my $name = $queue->{Name};
@@ -115,7 +115,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
     {  id          => $_->Id,
        Name        => $_->Name,
        Description => $_->Description,
-       Lifecycle   => $_->Lifecycle->name,
+       Lifecycle   => $_->Lifecycle->Name,
     }
 } grep $_, @queues;
 
@@ -123,14 +123,14 @@ my %lifecycle;
 
 for my $queue (@queues) {
     my $cycle = RT::Lifecycle->Load( $queue->{'Lifecycle'} );
-    $lifecycle{ lc $cycle->name } = $cycle;
+    $lifecycle{ lc $cycle->Name } = $cycle;
 }
 
 unless (@statuses) {
     my %seen;
     foreach my $set ( 'initial', 'active' ) {
         foreach my $lifecycle ( map $lifecycle{$_}, sort keys %lifecycle ) {
-            push @statuses, grep !$seen{ lc $_ }++, $lifecycle->valid($set);
+            push @statuses, grep !$seen{ lc $_ }++, $lifecycle->Valid($set);
         }
     }
 }
diff --git a/share/html/Elements/QueueSummaryByStatus b/share/html/Elements/QueueSummaryByStatus
index d2b2e73..90f88ca 100644
--- a/share/html/Elements/QueueSummaryByStatus
+++ b/share/html/Elements/QueueSummaryByStatus
@@ -113,7 +113,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
     {  id          => $_->Id,
        Name        => $_->Name,
        Description => $_->Description,
-       Lifecycle   => $_->Lifecycle->name,
+       Lifecycle   => $_->Lifecycle->Name,
     }
 } grep $_, @queues;
 
@@ -122,7 +122,7 @@ my %lifecycle;
 
 for my $queue (@queues) {
     my $cycle = RT::Lifecycle->Load( $queue->{'Lifecycle'} );
-    $lifecycle{ lc $cycle->name } = $cycle;
+    $lifecycle{ lc $cycle->Name } = $cycle;
 }
 
 unless (@statuses) {
diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index 9e9a125..9b25235 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -72,10 +72,10 @@ if ( $TicketObj ) {
     }
 }
 elsif ( $QueueObj ) {
-    @status = $QueueObj->Lifecycle->valid;
+    @status = $QueueObj->Lifecycle->Valid;
 }
 else {
-    @status = RT::Queue->Lifecycle->valid;
+    @status = RT::Queue->Lifecycle->Valid;
 }
 </%INIT>
 <%ARGS>
diff --git a/t/lifecycles/basics.t b/t/lifecycles/basics.t
index 929cb72..2bf3c46 100644
--- a/t/lifecycles/basics.t
+++ b/t/lifecycles/basics.t
@@ -22,8 +22,8 @@ diag "check basic API";
 {
     my $schema = $general->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
-    is $schema->name, 'default', "it's a default schema";
-    is join(', ', sort $schema->valid),
+    is $schema->Name, 'default', "it's a default schema";
+    is join(', ', sort $schema->Valid),
         join(', ', sort qw(new open stalled resolved rejected deleted)),
         'this is the default set from our config file';
 }
diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index afe45ce..913b2a6 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -30,11 +30,11 @@ diag "check basic API";
 {
     my $schema = $general->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
-    is $schema->name, 'default', "it's a default schema";
+    is $schema->Name, 'default', "it's a default schema";
 
     $schema = $delivery->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
-    is $schema->name, 'delivery', "it's a delivery schema";
+    is $schema->Name, 'delivery', "it's a delivery schema";
 }
 
 diag "dates on create for default schema";

commit 25ea5ed0f3aded174f44dee5252bb83fa8e6fbe9
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 04:44:38 2010 +0300

    camel casing in lifecycles

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 18ad629..9ea3212 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -53,7 +53,7 @@ package RT::Lifecycle;
 
 our %LIFECYCLES;
 our %LIFECYCLES_CACHE;
-__PACKAGE__->register_rights;
+__PACKAGE__->RegisterRights;
 
 # cache structure:
 #    {
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index fd05ff3..cea9c58 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -2654,7 +2654,7 @@ sub _MergeInto {
     }
 
 
-    my $default_inactive = $self->QueueObj->Lifecycle->default_inactive;
+    my $default_inactive = $self->QueueObj->Lifecycle->DefaultInactive;
     if ( $default_inactive ne $self->__Value('Status') ) {
         my ( $status_val, $status_msg )
             = $self->__Set( Field => 'Status', Value => $default_inactive );
@@ -3101,7 +3101,7 @@ sub SetStatus {
         return (0, $self->loc("You can't change status from '[_1]' to '[_2]'.", $self->loc($old), $self->loc($new)));
     }
 
-    my $check_right = $lifecycle->check_right( $old => $new );
+    my $check_right = $lifecycle->CheckRight( $old => $new );
     unless ( $self->CurrentUserHasRight( $check_right ) ) {
         return ( 0, $self->loc('Permission Denied') );
     }
diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index 9b25235..b1a3a00 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -65,7 +65,7 @@ if ( $TicketObj ) {
 
     my %has = ();
     foreach my $next ( $lifecycle->Transitions( $current ) ) {
-        my $check = $lifecycle->check_right( $current => $next );
+        my $check = $lifecycle->CheckRight( $current => $next );
         $has{ $check } = $TicketObj->CurrentUserHasRight( $check )
             unless exists $has{ $check };
         push @status, $next if $has{ $check };

commit 0ff473d944af99cb92359989708f000a96cd07d1
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 04:50:39 2010 +0300

    camel casing in lifecycles

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 9ea3212..5711c5e 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -113,7 +113,7 @@ sub new {
     my $proto = shift;
     my $self = bless {}, ref($proto) || $proto;
 
-    $self->fill_cache unless keys %LIFECYCLES_CACHE;
+    $self->FillCache unless keys %LIFECYCLES_CACHE;
 
     return $self;
 }
@@ -152,7 +152,7 @@ Returns sorted list of the lifecycles' names.
 sub List {
     my $self = shift;
 
-    $self->fill_cache unless keys %LIFECYCLES_CACHE;
+    $self->FillCache unless keys %LIFECYCLES_CACHE;
 
     return sort grep length && $_ ne '__maps__', keys %LIFECYCLES_CACHE;
 }
@@ -242,7 +242,7 @@ sub IsInitial {
 }
 
 
-=head3 default_initial
+=head3 DefaultInitial
 
 Returns the "default" initial status for this lifecycle
 
@@ -304,20 +304,20 @@ sub IsInactive {
     return 0;
 }
 
-=head3 default_inactive
+=head3 DefaultInactive
 
 Returns the "default" inactive status for this lifecycle
 
 =cut
 
-sub default_inactive {
+sub DefaultInactive {
     my $self = shift;
     return $self->{data}->{default_inactive};
 }
 
 =head2 Transitions, rights, labels and actions.
 
-=head3 transitions
+=head3 Transitions
 
 Takes status and returns list of statuses it can be changed to.
 
@@ -354,14 +354,14 @@ sub IsTransition {
     return 0;
 }
 
-=head3 check_right
+=head3 CheckRight
 
 Takes two statuses (from -> to) and returns the right that should
 be checked on the ticket.
 
 =cut
 
-sub check_right {
+sub CheckRight {
     my $self = shift;
     my $from = shift;
     my $to = shift;
@@ -376,10 +376,10 @@ sub check_right {
     return $to eq 'deleted' ? 'DeleteTicket' : 'ModifyTicket';
 }
 
-sub register_rights {
+sub RegisterRights {
     my $self = shift;
 
-    $self->fill_cache unless keys %LIFECYCLES_CACHE;
+    $self->FillCache unless keys %LIFECYCLES_CACHE;
 
     my %tmp;
     foreach my $lifecycle ( values %LIFECYCLES_CACHE ) {
@@ -409,7 +409,7 @@ sub register_rights {
     }
 }
 
-=head3 actions
+=head3 Actions
 
 Takes a status and returns list of defined actions for the status. Each
 element in the list is a hash reference with the following key/value
@@ -429,11 +429,11 @@ pairs:
 
 =cut
 
-sub actions {
+sub Actions {
     my $self = shift;
     my $from = shift || return ();
 
-    $self->fill_cache unless keys %LIFECYCLES_CACHE;
+    $self->FillCache unless keys %LIFECYCLES_CACHE;
 
     my @res = grep $_->{'from'} eq $from || ( $_->{'from'} eq '*' && $_->{'to'} ne $from ),
         @{ $self->{'data'}{'actions'} };
@@ -603,7 +603,7 @@ sub fill_cache {
 
 sub for_localization {
     my $self = shift;
-    $self->fill_cache unless keys %LIFECYCLES_CACHE;
+    $self->FillCache unless keys %LIFECYCLES_CACHE;
 
     my @res = ();
 
@@ -628,7 +628,7 @@ sub _store_lifecycles {
         description => 'all system lifecycles',
         content => \%LIFECYCLES,
     );
-    $self->fill_cache;
+    $self->FillCache;
     $self->Load( $name );
     return ($status, loc("Couldn't store lifecycle")) unless $status;
     return 1;
diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index 913b2a6..3f74a1f 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -285,7 +285,7 @@ diag "add partial map between general->delivery";
             'on way' => 'resolved',
         },
     };
-    RT::Lifecycle->fill_cache;
+    RT::Lifecycle->FillCache;
 }
 
 diag "check date changes on moving a ticket";
diff --git a/t/lifecycles/moving.t b/t/lifecycles/moving.t
index 864954c..730b6e8 100644
--- a/t/lifecycles/moving.t
+++ b/t/lifecycles/moving.t
@@ -46,7 +46,7 @@ diag "add partial map";
             new => 'ordered',
         },
     };
-    RT::Lifecycle->fill_cache;
+    RT::Lifecycle->FillCache;
 }
 
 diag "check moving with a partial map";

commit 8457bd4d0d6876bd82998f871dc508e63f7b8062
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 07:26:41 2010 +0300

    finish commit on camel casing lifecycles

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 5711c5e..1a2a0f9 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -546,7 +546,7 @@ sub set_actions {
     return (1, loc('Updated lifecycle with actions data'));
 }
 
-sub fill_cache {
+sub FillCache {
     my $self = shift;
 
     my $map = RT->Config->Get('Lifecycles') or return;
@@ -601,7 +601,7 @@ sub fill_cache {
     return;
 }
 
-sub for_localization {
+sub ForLocalization {
     my $self = shift;
     $self->FillCache unless keys %LIFECYCLES_CACHE;
 
@@ -694,7 +694,7 @@ sub _set_actions {
     return 1;
 }
 
-sub from_set {
+sub FromSet {
     my $self = shift;
     my $status = shift;
     foreach my $set ( qw(initial active inactive) ) {
@@ -703,7 +703,7 @@ sub from_set {
     return '';
 }
 
-sub map {
+sub Map {
     my $from = shift;
     my $to = shift;
     $to = RT::Lifecycle->Load( $to ) unless ref $to;
@@ -732,15 +732,15 @@ sub set_map {
     return (1, loc('Updated lifecycle with actions data'));
 }
 
-sub has_map {
+sub HasMap {
     my $self = shift;
-    my $map = $self->map( @_ );
+    my $map = $self->Map( @_ );
     return 0 unless $map && keys %$map;
     return 0 unless grep defined && length, values %$map;
     return 1;
 }
 
-sub no_maps {
+sub NoMaps {
     my $self = shift;
     my @list = $self->List;
     my @res;
@@ -748,17 +748,17 @@ sub no_maps {
         foreach my $to ( @list ) {
             next if $from eq $to;
             push @res, $from, $to
-                unless RT::Lifecycle->Load( $from )->has_map( $to );
+                unless RT::Lifecycle->Load( $from )->HasMap( $to );
         }
     }
     return @res;
 }
 
-sub queues {
+sub Queues {
     my $self = shift;
     require RT::Queues;
     my $queues = RT::Queues->new( RT->SystemUser );
-    $queues->limit( column => 'lifecycle', value => $self->Name );
+    $queues->Limit( FIELD => 'Lifecycle', VALUE => $self->Name );
     return $queues;
 }
 
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index cea9c58..0ebbab5 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -1713,10 +1713,10 @@ sub SetQueue {
     my $old_lifecycle = $self->QueueObj->Lifecycle;
     my $new_lifecycle = $NewQueueObj->Lifecycle;
     if ( $old_lifecycle->Name ne $new_lifecycle->Name ) {
-        unless ( $old_lifecycle->has_map( $new_lifecycle ) ) {
+        unless ( $old_lifecycle->HasMap( $new_lifecycle ) ) {
             return ( 0, $self->loc("There is no mapping for statuses between these queues. Contact your system administrator.") );
         }
-        $new_status = $old_lifecycle->map( $new_lifecycle )->{ $self->Status };
+        $new_status = $old_lifecycle->Map( $new_lifecycle )->{ $self->Status };
         return ( 0, $self->loc("Mapping between queues' lifecycles is incomplete. Contact your system administrator.") )
             unless $new_status;
     }

commit 112b00954c892866b07a75abfbab6076649b1a47
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 07:34:41 2010 +0300

    describe RT::Lifecycle->Queues

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 1a2a0f9..9a2a2a2 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -165,6 +165,20 @@ Returns name of the laoded lifecycle.
 
 sub Name { return $_[0]->{'name'} }
 
+=head2 Queues
+
+Returns L<RT::Queues> collection with queues that use this lifecycle.
+
+=cut
+
+sub Queues {
+    my $self = shift;
+    require RT::Queues;
+    my $queues = RT::Queues->new( RT->SystemUser );
+    $queues->Limit( FIELD => 'Lifecycle', VALUE => $self->Name );
+    return $queues;
+}
+
 =head2 Getting statuses and validating.
 
 Methods to get statuses in different sets or validating them.
@@ -754,14 +768,6 @@ sub NoMaps {
     return @res;
 }
 
-sub Queues {
-    my $self = shift;
-    require RT::Queues;
-    my $queues = RT::Queues->new( RT->SystemUser );
-    $queues->Limit( FIELD => 'Lifecycle', VALUE => $self->Name );
-    return $queues;
-}
-
 sub loc { return RT->SystemUser->loc( @_ ) }
 
 1;

commit 0b1ba49f99b5b6773f22f6f7f2d35498c957106e
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Nov 6 07:35:53 2010 +0300

    FromSet->StatusType with description

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 9a2a2a2..09eff9f 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -230,6 +230,22 @@ sub IsValid {
     return 0;
 }
 
+=head3 StatusType
+
+Takes a status and returns its type, one of 'initial', 'active' or
+'inactive'.
+
+=cut
+
+sub StatusType {
+    my $self = shift;
+    my $status = shift;
+    foreach my $type ( qw(initial active inactive) ) {
+        return $type if $self->IsValid( $status, $set );
+    }
+    return '';
+}
+
 =head3 Initial
 
 Returns an array of all initial statuses for the current lifecycle.
@@ -708,15 +724,6 @@ sub _set_actions {
     return 1;
 }
 
-sub FromSet {
-    my $self = shift;
-    my $status = shift;
-    foreach my $set ( qw(initial active inactive) ) {
-        return $set if $self->IsValid( $status, $set );
-    }
-    return '';
-}
-
 sub Map {
     my $from = shift;
     my $to = shift;

commit 0dc44e9087ca1216d2e13b509887ff3ef2e2c49f
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 07:31:41 2010 +0300

    typo in var name

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 09eff9f..f9222d2 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -241,7 +241,7 @@ sub StatusType {
     my $self = shift;
     my $status = shift;
     foreach my $type ( qw(initial active inactive) ) {
-        return $type if $self->IsValid( $status, $set );
+        return $type if $self->IsValid( $status, $type );
     }
     return '';
 }

commit 7259c0d3c3a461db136381c0de274f1e5a6a3cac
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 07:32:18 2010 +0300

    factor out RightsDescription from RegisterRights

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index f9222d2..65c46b6 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -406,9 +406,42 @@ sub CheckRight {
     return $to eq 'deleted' ? 'DeleteTicket' : 'ModifyTicket';
 }
 
+=head3 RegisterRights
+
+Registers all defined rights in the system, so they can be addigned
+to users. No need to call it, as it's called when module is loaded.
+
+=cut
+
 sub RegisterRights {
     my $self = shift;
 
+    my %rights = $self->RightsDescription;
+
+    require RT::ACE;
+
+    require RT::Queue;
+    my $RIGHTS = $RT::Queue::RIGHTS;
+
+    while ( my ($right, $description) = each %rights ) {
+        next if exists $RIGHTS->{ $right };
+
+        $RIGHTS->{ $right } = $description;
+        RT::Queue->AddRightCategories( $right => 'Status' );
+        $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+    }
+}
+
+=head3 RightsDescription
+
+Returns hash with description of rights that are defined for
+particular transitions.
+
+=cut
+
+sub RightsDescription {
+    my $self = shift;
+
     $self->FillCache unless keys %LIFECYCLES_CACHE;
 
     my %tmp;
@@ -419,12 +452,8 @@ sub RegisterRights {
         }
     }
 
-    require RT::ACE;
-    require RT::Queue;
-    my $RIGHTS = $RT::Queue::RIGHTS;
+    my %res;
     while ( my ($right, $transitions) = each %tmp ) {
-        next if exists $RIGHTS->{ $right };
-
         my (@from, @to);
         foreach ( @$transitions ) {
             ($from[@from], $to[@to]) = split / -> /, $_;
@@ -433,10 +462,9 @@ sub RegisterRights {
             . ( (grep $_ eq '*', @from)? '' : ' from '. join ', ', @from )
             . ( (grep $_ eq '*', @to  )? '' : ' to '. join ', ', @from );
 
-        $RIGHTS->{ $right } = $description;
-        RT::Queue->AddRightCategories( $right => 'Status' );
-        $RT::ACE::LOWERCASERIGHTNAMES{ lc $right } = $right;
+        $res{ $right } = $description;
     }
+    return %res;
 }
 
 =head3 Actions

commit f2d8c11f1d0d5a1d34e415f94ff9b341c42a6717
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 07:40:34 2010 +0300

    adjust ForLocalization method for new storage format

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 65c46b6..2628c8f 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -669,9 +669,9 @@ sub ForLocalization {
     foreach my $lifecycle ( values %LIFECYCLES ) {
         push @res,
             grep defined && length,
-            map $_->[0],
+            map $_->{'label'},
             grep ref($_),
-            values %{ $lifecycle->{'actions'} || {} };
+            @{ $lifecycle->{'actions'} || [] };
     }
 
     my %seen;

commit 263c53eea030f1929f91e479701f8e061176dc07
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 07:41:27 2010 +0300

    announce rights and its descriptions for localization

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 2628c8f..9a0c444 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -674,6 +674,8 @@ sub ForLocalization {
             @{ $lifecycle->{'actions'} || [] };
     }
 
+    push @res, $self->RightsDescription;
+
     my %seen;
     return grep !$seen{lc $_}++, @res;
 }

commit e058a7742ad3e8fdc0b97bb0ae211dbf17e64e95
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 07:46:31 2010 +0300

    move and describe method

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 9a0c444..0be763b 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -503,6 +503,38 @@ sub Actions {
     return grep defined, @res;
 }
 
+=head2 Localization
+
+=head3 ForLocalization
+
+A class method that takes no arguments and returns list of strings
+that require translation.
+
+=cut
+
+sub ForLocalization {
+    my $self = shift;
+    $self->FillCache unless keys %LIFECYCLES_CACHE;
+
+    my @res = ();
+
+    push @res, @{ $LIFECYCLES_CACHE{''}{''} || [] };
+    foreach my $lifecycle ( values %LIFECYCLES ) {
+        push @res,
+            grep defined && length,
+            map $_->{'label'},
+            grep ref($_),
+            @{ $lifecycle->{'actions'} || [] };
+    }
+
+    push @res, $self->RightsDescription;
+
+    my %seen;
+    return grep !$seen{lc $_}++, @res;
+}
+
+sub loc { return RT->SystemUser->loc( @_ ) }
+
 =head2 Creation and manipulation
 
 =head3 create
@@ -659,27 +691,6 @@ sub FillCache {
     return;
 }
 
-sub ForLocalization {
-    my $self = shift;
-    $self->FillCache unless keys %LIFECYCLES_CACHE;
-
-    my @res = ();
-
-    push @res, @{ $LIFECYCLES_CACHE{''}{''} || [] };
-    foreach my $lifecycle ( values %LIFECYCLES ) {
-        push @res,
-            grep defined && length,
-            map $_->{'label'},
-            grep ref($_),
-            @{ $lifecycle->{'actions'} || [] };
-    }
-
-    push @res, $self->RightsDescription;
-
-    my %seen;
-    return grep !$seen{lc $_}++, @res;
-}
-
 sub _store_lifecycles {
     my $self = shift;
     my $name = shift;
@@ -805,6 +816,4 @@ sub NoMaps {
     return @res;
 }
 
-sub loc { return RT->SystemUser->loc( @_ ) }
-
 1;

commit fb30567bb73801dcc7dcff46a6b553db2689211a
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 07:55:09 2010 +0300

    describe methods related to move maps

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 0be763b..83d5287 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -503,6 +503,58 @@ sub Actions {
     return grep defined, @res;
 }
 
+=head2 Moving tickets between lifecycles
+
+=head3 Map
+
+Takes lifecycle as a name string or an object and returns a hash reference with
+move map from this cycle to provided.
+
+=cut
+
+sub Map {
+    my $from = shift; # self
+    my $to = shift;
+    $to = RT::Lifecycle->Load( $to ) unless ref $to;
+    return $LIFECYCLES{'__maps__'}{ $from->Name .' -> '. $to->Name } || {};
+}
+
+=head3 HasMap
+
+Takes a lifecycle as a name string or an object and returns true if move map
+defined for move from this cycle to provided.
+
+=cut
+
+sub HasMap {
+    my $self = shift;
+    my $map = $self->Map( @_ );
+    return 0 unless $map && keys %$map;
+    return 0 unless grep defined && length, values %$map;
+    return 1;
+}
+
+=head3 NoMaps
+
+Takes no arguments and returns hash with pairs that has no
+move maps.
+
+=cut
+
+sub NoMaps {
+    my $self = shift;
+    my @list = $self->List;
+    my @res;
+    foreach my $from ( @list ) {
+        foreach my $to ( @list ) {
+            next if $from eq $to;
+            push @res, $from, $to
+                unless RT::Lifecycle->Load( $from )->HasMap( $to );
+        }
+    }
+    return @res;
+}
+
 =head2 Localization
 
 =head3 ForLocalization
@@ -765,13 +817,6 @@ sub _set_actions {
     return 1;
 }
 
-sub Map {
-    my $from = shift;
-    my $to = shift;
-    $to = RT::Lifecycle->Load( $to ) unless ref $to;
-    return $LIFECYCLES{'__maps__'}{ $from->Name .' -> '. $to->Name } || {};
-}
-
 sub set_map {
     my $self = shift;
     my $to = shift;
@@ -794,26 +839,4 @@ sub set_map {
     return (1, loc('Updated lifecycle with actions data'));
 }
 
-sub HasMap {
-    my $self = shift;
-    my $map = $self->Map( @_ );
-    return 0 unless $map && keys %$map;
-    return 0 unless grep defined && length, values %$map;
-    return 1;
-}
-
-sub NoMaps {
-    my $self = shift;
-    my @list = $self->List;
-    my @res;
-    foreach my $from ( @list ) {
-        foreach my $to ( @list ) {
-            next if $from eq $to;
-            push @res, $from, $to
-                unless RT::Lifecycle->Load( $from )->HasMap( $to );
-        }
-    }
-    return @res;
-}
-
 1;

commit 8b06287beec52bf0a90aac915b19e841fd574162
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 11:51:16 2010 +0300

    Rename Maps in lifecycles to MoveMaps

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 83d5287..b87bca3 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -505,43 +505,43 @@ sub Actions {
 
 =head2 Moving tickets between lifecycles
 
-=head3 Map
+=head3 MoveMap
 
 Takes lifecycle as a name string or an object and returns a hash reference with
 move map from this cycle to provided.
 
 =cut
 
-sub Map {
+sub MoveMap {
     my $from = shift; # self
     my $to = shift;
     $to = RT::Lifecycle->Load( $to ) unless ref $to;
     return $LIFECYCLES{'__maps__'}{ $from->Name .' -> '. $to->Name } || {};
 }
 
-=head3 HasMap
+=head3 HasMoveMap
 
 Takes a lifecycle as a name string or an object and returns true if move map
 defined for move from this cycle to provided.
 
 =cut
 
-sub HasMap {
+sub HasMoveMap {
     my $self = shift;
-    my $map = $self->Map( @_ );
+    my $map = $self->MoveMap( @_ );
     return 0 unless $map && keys %$map;
     return 0 unless grep defined && length, values %$map;
     return 1;
 }
 
-=head3 NoMaps
+=head3 NoMoveMaps
 
 Takes no arguments and returns hash with pairs that has no
 move maps.
 
 =cut
 
-sub NoMaps {
+sub NoMoveMaps {
     my $self = shift;
     my @list = $self->List;
     my @res;
@@ -549,7 +549,7 @@ sub NoMaps {
         foreach my $to ( @list ) {
             next if $from eq $to;
             push @res, $from, $to
-                unless RT::Lifecycle->Load( $from )->HasMap( $to );
+                unless RT::Lifecycle->Load( $from )->HasMoveMap( $to );
         }
     }
     return @res;
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index 0ebbab5..a05b962 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -1713,10 +1713,10 @@ sub SetQueue {
     my $old_lifecycle = $self->QueueObj->Lifecycle;
     my $new_lifecycle = $NewQueueObj->Lifecycle;
     if ( $old_lifecycle->Name ne $new_lifecycle->Name ) {
-        unless ( $old_lifecycle->HasMap( $new_lifecycle ) ) {
+        unless ( $old_lifecycle->HasMoveMap( $new_lifecycle ) ) {
             return ( 0, $self->loc("There is no mapping for statuses between these queues. Contact your system administrator.") );
         }
-        $new_status = $old_lifecycle->Map( $new_lifecycle )->{ $self->Status };
+        $new_status = $old_lifecycle->MoveMap( $new_lifecycle )->{ $self->Status };
         return ( 0, $self->loc("Mapping between queues' lifecycles is incomplete. Contact your system administrator.") )
             unless $new_status;
     }

commit b13c6ed81e857c750b636ad4d686996a58726aef
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Nov 10 16:38:52 2010 +0300

    delete all manipulation routines from lifecycles

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index b87bca3..7ea6dbc 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -587,114 +587,10 @@ sub ForLocalization {
 
 sub loc { return RT->SystemUser->loc( @_ ) }
 
-=head2 Creation and manipulation
-
-=head3 create
-
-Creates a new lifecycle in the DB. Takes a param hash with
-'name', 'initial', 'active', 'inactive' and 'transitions' keys.
-
-All arguments except 'name' are optional and can be filled later
-with other methods.
-
-Returns (status, message) pair, status is false on error.
-
-=cut
-
-sub create {
-    my $self = shift;
-    my %args = (
-        name => undef,
-        initial => undef,
-        active => undef,
-        inactive => undef,
-        transitions => undef,
-        actions => undef,
-        @_
-    );
-    @{ $self }{qw(name data)} = (undef, undef);
-
-    my $name = delete $args{'name'};
-    return (0, loc('Invalid lifecycle name'))
-        unless defined $name && length $name;
-    return (0, loc('Already exist'))
-        if $LIFECYCLES_CACHE{ $name };
-
-    foreach my $method (qw(_set_defaults _set_statuses _set_transitions _set_actions)) {
-        my ($status, $msg) = $self->$method( %args, name => $name );
-        return ($status, $msg) unless $status;
-    }
-
-    my ($status, $msg) = $self->_store_lifecycles( $name );
-    return ($status, $msg) unless $status;
-
-    return (1, loc('Created a new lifecycle'));
-}
-
-sub set_statuses {
-    my $self = shift;
-    my %args = (
-        initial  => [],
-        active   => [],
-        inactive => [],
-        @_
-    );
-
-    my $name = $self->Name or return (0, loc("Lifecycle is not loaded"));
-
-    my ($status, $msg) = $self->_set_statuses( %args, name => $name );
-    return ($status, $msg) unless $status;
-
-    ($status, $msg) = $self->_store_lifecycles( $name );
-    return ($status, $msg) unless $status;
-
-    return (1, loc('Updated lifecycle'));
-}
-
-
-
-
-sub set_transitions {
-    my $self = shift;
-    my %args = @_;
-
-    my $name = $self->Name or return (0, loc("Lifecycle is not loaded"));
-
-    my ($status, $msg) = $self->_set_transitions(
-        transitions => \%args, name => $name
-    );
-    return ($status, $msg) unless $status;
-
-    ($status, $msg) = $self->_store_lifecycles( $name );
-    return ($status, $msg) unless $status;
-
-    return (1, loc('Updated lifecycle with transitions data'));
-}
-
-sub set_actions {
-    my $self = shift;
-    my %args = @_;
-
-    my $name = $self->Name or return (0, loc("Lifecycle is not loaded"));
-
-    my ($status, $msg) = $self->_set_actions(
-        actions => \%args, name => $name
-    );
-    return ($status, $msg) unless $status;
-
-    ($status, $msg) = $self->_store_lifecycles( $name );
-    return ($status, $msg) unless $status;
-
-    return (1, loc('Updated lifecycle with actions data'));
-}
-
 sub FillCache {
     my $self = shift;
 
     my $map = RT->Config->Get('Lifecycles') or return;
-#    my $map = $RT::System->first_attribute('Lifecycles')
-#        or return;
-#    $map = $map->content or return;
 
     %LIFECYCLES_CACHE = %LIFECYCLES = %$map;
     $_ = { %$_ } foreach values %LIFECYCLES_CACHE;
@@ -743,100 +639,4 @@ sub FillCache {
     return;
 }
 
-sub _store_lifecycles {
-    my $self = shift;
-    my $name = shift;
-    my ($status, $msg) = $RT::System->set_attribute(
-        name => 'Lifecycles',
-        description => 'all system lifecycles',
-        content => \%LIFECYCLES,
-    );
-    $self->FillCache;
-    $self->Load( $name );
-    return ($status, loc("Couldn't store lifecycle")) unless $status;
-    return 1;
-}
-
-sub _set_statuses {
-    my $self = shift;
-    my %args = @_;
-
-    my @all;
-    my %tmp = (
-        initial  => [],
-        active   => [],
-        inactive => [],
-    );
-    foreach my $type ( qw(initial active inactive) ) {
-        foreach my $status ( grep defined && length, @{ $args{ $type } || [] } ) {
-            return (0, loc('Status should contain ASCII characters only. Translate via po files.'))
-                unless $status =~ /^[a-zA-Z0-9.,! ]+$/;
-            return (0, loc('Statuses must be unique within a lifecycle'))
-                if grep lc($_) eq lc($status), @all;
-            push @all, $status;
-            push @{ $tmp{ $type } }, $status;
-        }
-    }
-
-    $LIFECYCLES{ $args{'name'} }{ $_ } = $tmp{ $_ }
-        foreach qw(initial active inactive);
-
-    return 1;
-}
-
-
-sub _set_defaults {
-    my $self = shift;
-    my %args = @_;
-
-    $LIFECYCLES{ $args{'name'} }{$_ } = $args{ $_ }
-        foreach qw(default_initial default_inactive);
-
-    return 1;
-}
-
-
-
-
-
-sub _set_transitions {
-    my $self = shift;
-    my %args = @_;
-
-    # XXX, TODO: more tests on data
-    $LIFECYCLES{ $args{'name'} }{'transitions'} = $args{'transitions'};
-    return 1;
-}
-
-sub _set_actions {
-    my $self = shift;
-    my %args = @_;
-
-    # XXX, TODO: more tests on data
-    $LIFECYCLES{ $args{'name'} }{'actions'} = $args{'actions'};
-    return 1;
-}
-
-sub set_map {
-    my $self = shift;
-    my $to = shift;
-    $to = RT::Lifecycle->Load( $to ) unless ref $to;
-    my %map = @_;
-    $map{ lc $_ } = delete $map{ $_ } foreach keys %map;
-
-    return (0, loc("Lifecycle is not loaded"))
-        unless $self->Name;
-
-    return (0, loc("Lifecycle is not loaded"))
-        unless $to->Name;
-
-
-    $LIFECYCLES{'__maps__'}{ $self->Name .' -> '. $to->Name } = \%map;
-
-    my ($status, $msg) = $self->_store_lifecycles( $self->Name );
-    return ($status, $msg) unless $status;
-
-    return (1, loc('Updated lifecycle with actions data'));
-}
-
 1;

commit 0a159f4086c4750c4e8f4cdece59502b25b6e469
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Nov 11 13:10:59 2010 +0300

    don't check ModifyTicket, as each status change can be protected with own status

diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index cb03de3..14d5c22 100755
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -368,37 +368,34 @@ if ( $request_path !~ qr{^/SelfService/} ) {
                 $actions->child( forward => title => loc('Forward'), path => "/Ticket/Forward.html?id=" . $id, );
             }
 
-            if ( $can{'ModifyTicket'} ) {
-                my $current   = $obj->Status;
-                my $lifecycle = $obj->QueueObj->Lifecycle;
-                my $i         = 1;
+            my $current   = $obj->Status;
+            my $lifecycle = $obj->QueueObj->Lifecycle;
+            my $i         = 1;
+            foreach my $info ( $lifecycle->Actions($current) ) {
+                my $next = $info->{'to'};
+                next unless $lifecycle->IsTransition( $current => $next );
 
-                foreach my $info ( $lifecycle->Actions($current) ) {
-                    my $next = $info->{'to'};
-                    next unless $lifecycle->IsTransition( $current => $next );
+                my $check = $lifecycle->CheckRight( $current => $next );
+                $can{$check} = $obj->CurrentUserHasRight($check) unless exists $can{$check};
+                next unless $can{$check};
 
-                    my $check = $lifecycle->CheckRight( $current => $next );
-                    $can{$check} = $obj->CurrentUserHasRight($check) unless exists $can{$check};
-                    next unless $can{$check};
 
+                my $action = $info->{'update'} || '';
 
-                    my $action = $info->{'update'} || '';
 
+                my $url = '/Ticket/';
+                if ($action) {
 
-                    my $url = '/Ticket/';
-                    if ($action) {
-
-                        $url .= "Update.html?" . $query_string->(Action => $action,
-                                               DefaultStatus => $next,
-                                               id            => $id
-                                             );
-                    } else {
-                        $url .= "Display.html?" . $query_string->( Status => $next, id => $id );
-                    }
-                    $actions->child( loc( $info->{'label'} || ucfirst($next) ) => path => $url);
+                    $url .= "Update.html?" . $query_string->(Action => $action,
+                                           DefaultStatus => $next,
+                                           id            => $id
+                                         );
+                } else {
+                    $url .= "Display.html?" . $query_string->( Status => $next, id => $id );
                 }
-
+                $actions->child( loc( $info->{'label'} || ucfirst($next) ) => path => $url);
             }
+
             if ( $can{OwnTicket} ) {
                 if ( $obj->OwnerObj->Id == RT->Nobody->id
                      && ( $can{'ModifyTicket'} or $can{'TakeTicket'} ) ) {

commit e5dc4440fb453f854eefd4600b1d9d12bd9b692f
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Nov 11 14:41:23 2010 +0300

    tidy code a little bit

diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index b1a3a00..8daa5cf 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -46,12 +46,13 @@
 %#
 %# END BPS TAGGED BLOCK }}}
 <select name="<%$Name%>">
-%if ($DefaultValue) {
-<option value=""<% !$Default && qq[ selected="selected"] |n %>><%$DefaultLabel%></option>
-%}
-%foreach my $status (@status) {
-%next if ($SkipDeleted && $status eq 'deleted');
-<option value="<%$status%>"<% (defined $Default && $status eq $Default) && qq[ selected="selected"] |n %>><%loc($status)%></option>
+% if ( $DefaultValue ) {
+<option value=""<% !$Default && qq[ selected="selected"] |n %>><% $DefaultLabel %></option>
+% }
+% foreach my $status (@status) {
+% next if ($SkipDeleted && $status eq 'deleted');
+% my $selected = defined $Default && $status eq $Default ? 'selected="selected"' : '';
+<option value="<% $status %>" <% $selected |n %>><% loc($status) %></option>
 % }
 </select>
 <%INIT>

commit c6f7c26a57f7642df9890f45f3a6044c0a4bb5a6
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Nov 11 15:15:27 2010 +0300

    support undef argument in Lifecycle->Transitions

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 7ea6dbc..9e88bab 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -351,8 +351,11 @@ sub DefaultInactive {
 
 Takes status and returns list of statuses it can be changed to.
 
-If status is ommitted then returns a hash with all possible transitions
-in the following format:
+Is status is empty or undefined then returns list of statuses for
+a new ticket.
+
+If argument is ommitted then returns a hash with all possible
+transitions in the following format:
 
     status_x => [ next_status, next_status, ... ],
     status_y => [ next_status, next_status, ... ],
@@ -361,12 +364,11 @@ in the following format:
 
 sub Transitions {
     my $self = shift;
+    return %{ $self->{'data'}{'transitions'} || {} }
+        unless @_;
+
     my $status = shift;
-    if ( $status ) {
-        return @{ $self->{'data'}{'transitions'}{ $status } || [] };
-    } else {
-        return %{ $self->{'data'}{'transitions'} || {} };
-    }
+    return @{ $self->{'data'}{'transitions'}{ $status || '' } || [] };
 }
 
 =head1 IsTransition

commit 10b68454e380f3a35eb419848de6e995e8751dc9
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Nov 11 15:20:45 2010 +0300

    pre-fill transitions from '' in the cache

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 9e88bab..acb376c 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -613,6 +613,10 @@ sub FillCache {
         my %seen;
         @res = grep !$seen{ lc $_ }++, @res;
         $lifecycle->{''} = \@res;
+
+        unless ( $lifecycle->{'transitions'}{''} ) {
+            $lifecycle->{'transitions'}{''} = [ grep $_ ne 'deleted', @res ];
+        }
     }
     foreach my $type ( qw(initial active inactive), '' ) {
         my %seen;

commit e56ad7ad7cd6cbdd93686b0bc5b99b5145377be0
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Nov 11 15:24:26 2010 +0300

    describe transition from '' in the config

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 18fab92..e22e891 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1818,8 +1818,7 @@ ticket, RT will use the L<"default_initial"> status.
 =item initial
 
 You can define multiple B<initial> statuses for tickets in a
-given lifecycle. Newly created tickets can only have
-a status that's listed as initial.
+given lifecycle.
 
 A ticket's B<Created> date is set immediately upon ticket creation.
 RT will automatically set its B<Started> date when you change
@@ -1870,6 +1869,7 @@ 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)],
@@ -1880,6 +1880,10 @@ all possible transitions in each lifecycle using the following format:
         ...
     },
 
+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.
+
 =head3 Protecting status changes with rights
 
 A transition or group of transitions can be protected by a specific right.

commit cc233ee3b1b219ade558f08d6e37628458bc17cd
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Nov 11 15:25:28 2010 +0300

    clarify docs on lifecycles a little bit

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index e22e891..1785bf0 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1820,7 +1820,6 @@ ticket, RT will use the L<"default_initial"> status.
 You can define multiple B<initial> statuses for tickets in a
 given lifecycle.
 
-A ticket's B<Created> date is set immediately upon ticket creation.
 RT will automatically set its B<Started> date when you change
 a ticket's status from an B<initial> state to an B<active> or B<inactive>
 status.
@@ -1842,13 +1841,14 @@ RT will automatically set the B<Resolved> state when a ticket's status is
 changed from an B<Initial> or B<Active> status to an B<Inactive> status.
 
 B<deleted> is still a special status and protected by the B<DeleteTicket>
-right. If you don't want to allow ticket deletion at any time simply
-don't include it in your lifecycle.
+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.
 
 =item default_inactive
 
-you can specify a set of statuses which
-RT will treat as valid "inactive" statuses for tickets.
+You can specify a set of statuses which RT will treat as valid "inactive"
+statuses for tickets.
 
 If you (or your code) doesn't specify a status when resolving a
 ticket, RT will use the L<"default_inactive"> status.

commit 388136418df334bf4eaae6de50115327cc72ad26
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 11:46:41 2010 +0300

    support RT::Lifecycle->IsTransition( '' => 'foo' )

diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index acb376c..2187c9d 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -380,7 +380,7 @@ transition and false otherwise.
 
 sub IsTransition {
     my $self = shift;
-    my $from = shift or return 0;
+    my $from = shift;
     my $to   = shift or return 0;
     return 1 if grep lc($_) eq lc($to), $self->Transitions($from);
     return 0;

commit eeff0a2d127f2f5701821fe373bb7a5703da056b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 11:48:10 2010 +0300

    allow to create tickets only with status from '' transitions

diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index a05b962..621e8c4 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -299,17 +299,24 @@ sub Create {
             $self->loc( "No permission to create tickets in the queue '[_1]'", $QueueObj->Name));
     }
 
-    if ( ! defined $args{'Status'}) {
-        $args{'Status'} = $QueueObj->Lifecycle->DefaultInitial();
+    my $cycle = $QueueObj->Lifecycle;
+    unless ( defined $args{'Status'} && length $args{'Status'} ) {
+        $args{'Status'} = $cycle->DefaultInitial;
     }
 
-    unless ( $QueueObj->IsValidStatus( $args{'Status'} )
-            && $QueueObj->Lifecycle->IsInitial( $args{'Status'} )) {
+    unless ( $cycle->IsValid( $args{'Status'} ) ) {
         return ( 0, 0,
             $self->loc("Status '[_1]' isn't a valid status for tickets in this queue.",
-                $self->loc($args{'Status'})));
+                $self->loc($args{'Status'}))
+        );
     }
 
+    unless ( $cycle->IsTransition( '' => $args{'Status'} ) ) {
+        return ( 0, 0,
+            $self->loc("New tickets can not have status '[_1]' in this queue.",
+                $self->loc($args{'Status'}))
+        );
+    }
 
 
 
@@ -353,17 +360,9 @@ sub Create {
     if ( defined $args{'Started'} ) {
         $Started->Set( Format => 'ISO', Value => $args{'Started'} );
     }
-    # We sort of want to ask "is this not an initial state
-    # But some schemes require active statuses to be duplicated
-    # in the initial state list so that tickets can be created
-    # in those states already open
-    #
-    # Instead, we check to make sure that it's either an "active" or "inactive" status
-    elsif (
-        $QueueObj->Lifecycle->IsActive($args{'Status'}) ||
-        $QueueObj->Lifecycle->IsInactive($args{'Status'})
 
-    ){
+    # If the status is not an initial status, set the started date
+    elsif ( !$cycle->IsInitial($args{'Status'}) ) {
         $Started->SetToNow;
     }
 
@@ -373,7 +372,7 @@ sub Create {
     }
 
     #If the status is an inactive status, set the resolved date
-    elsif ( $QueueObj->Lifecycle->IsInactive( $args{'Status'} ) )
+    elsif ( $cycle->IsInactive( $args{'Status'} ) )
     {
         $RT::Logger->debug( "Got a ". $args{'Status'}
             ."(inactive) ticket with undefined resolved date. Setting to now."
@@ -607,7 +606,7 @@ sub Create {
     # TODO: Adding link may fire scrips on other end and those scrips
     # could create transactions on this ticket before 'Create' transaction.
     #
-    # We should implement different Lifecycle: record 'Create' transaction,
+    # We should implement different lifecycle: record 'Create' transaction,
     # create links and only then fire create transaction's scrips.
     #
     # Ideal variant: add all links without firing scrips, record create

commit 41d2bb08a21356bef8391e6146ba3ee6541d576e
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 11:55:28 2010 +0300

    SelectStatus: show only ('' -> *) when queue is provided

diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index 8daa5cf..71a2698 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -73,7 +73,7 @@ if ( $TicketObj ) {
     }
 }
 elsif ( $QueueObj ) {
-    @status = $QueueObj->Lifecycle->Valid;
+    @status = $QueueObj->Lifecycle->Transitions('');
 }
 else {
     @status = RT::Queue->Lifecycle->Valid;

commit d8017f6ab0b1feb82c0ac1365fd3ecc915196034
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 11:57:16 2010 +0300

    allow to pass just list of statuses into SelectStatus

diff --git a/share/html/Elements/SelectStatus b/share/html/Elements/SelectStatus
index 71a2698..06e3518 100644
--- a/share/html/Elements/SelectStatus
+++ b/share/html/Elements/SelectStatus
@@ -60,7 +60,10 @@
 
 
 my @status;
-if ( $TicketObj ) {
+if ( @Statuses ) {
+    @status = @Statuses;
+}
+elsif ( $TicketObj ) {
     my $current = $TicketObj->Status;
     my $lifecycle = $TicketObj->QueueObj->Lifecycle;
 
@@ -81,8 +84,11 @@ else {
 </%INIT>
 <%ARGS>
 $Name => undef
+
+ at Statuses => ()
 $TicketObj => undef
 $QueueObj => undef
+
 $Default => ''
 $SkipDeleted => 0
 $DefaultValue => 1

commit 2e62dcb892c095289cb18b37faa30d1756cc36af
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 12:00:32 2010 +0300

    change configs

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 1785bf0..db9ea1e 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1987,12 +1987,13 @@ you can not move tickets between queues with these lifecycles.
 Set(%Lifecycles,
     default => {
         default_initial => 'new',
-        initial         => [ 'new', 'open' ],
+        initial         => [ 'new' ],
         active          => [ 'open', 'stalled' ],
         inactive        => [ 'resolved', 'rejected', 'deleted' ],
         default_inactive => 'resolved',
 
         transitions => {
+            ''       => [qw(new open resolved)],
 
             # from   => [ to list ],
             new      => [qw(open stalled resolved rejected deleted)],
diff --git a/t/lifecycles/utils.pl b/t/lifecycles/utils.pl
index 33813e9..19daf17 100644
--- a/t/lifecycles/utils.pl
+++ b/t/lifecycles/utils.pl
@@ -10,10 +10,11 @@ $config = <<END;
 Set(\%Lifecycles,
     default => {
         default_initial => 'new',
-        initial  => [qw(new open resolved )],
+        initial  => [qw(new)],
         active   => [qw(open stalled)],
         inactive => [qw(resolved rejected deleted)],
         transitions => {
+            ''       => [qw(new open resolved)],
             new      => [qw(open resolved rejected deleted)],
             open     => [qw(stalled resolved rejected deleted)],
             stalled  => [qw(open)],

commit 4cdd2d509dd1be789be919ee69d8c4d6008a2e09
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 12:00:55 2010 +0300

    make sure all uses of SelectStatus are correct

diff --git a/share/html/SelfService/Update.html b/share/html/SelfService/Update.html
index ef9d8df..5b83032 100755
--- a/share/html/SelfService/Update.html
+++ b/share/html/SelfService/Update.html
@@ -60,7 +60,7 @@
             <&|/l&>Status</&>
         </td>
         <td class="value">
-            <& /Elements/SelectStatus, Name=>"Status", DefaultLabel => loc("[_1] (Unchanged)", loc($Ticket->Status)), Default => $ARGS{'Status'} || ($Ticket->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
+            <& /Elements/SelectStatus, Name => "Status", TicketObj => $Ticket, DefaultLabel => loc("[_1] (Unchanged)", loc($Ticket->Status)), Default => $ARGS{'Status'} || ($Ticket->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
         </td>
     </tr>
     <tr>
diff --git a/share/html/Ticket/Create.html b/share/html/Ticket/Create.html
index 128fcb6..3162580 100755
--- a/share/html/Ticket/Create.html
+++ b/share/html/Ticket/Create.html
@@ -81,10 +81,10 @@
                 comp => '/Elements/SelectStatus',
                 args => {
                     Name            => "Status",
-                    Default         => $ARGS{Status} || 'new',
+                    Default         => $ARGS{Status} || $QueueObj->Lifecycle->DefaultInitial,
                     DefaultValue    => 0,
                     SkipDeleted     => 1,
-                    QueueObj        => $QueueObj
+                    QueueObj        => $QueueObj,
                 },
             },
             {   name => 'Owner',
diff --git a/share/html/Ticket/Elements/EditBasics b/share/html/Ticket/Elements/EditBasics
index 31249b6..35e90ec 100755
--- a/share/html/Ticket/Elements/EditBasics
+++ b/share/html/Ticket/Elements/EditBasics
@@ -64,7 +64,7 @@ unless ( @fields ) {
                 DefaultLabel => loc("[_1] (Unchanged)",loc($TicketObj->Status)),
                 Default => $defaults{'Status'} || undef,
                 TicketObj => $TicketObj,
-                QueueObj => $TicketObj->QueueObj
+                QueueObj => $TicketObj->QueueObj,
             },
         },
         {   name => 'Queue',
diff --git a/share/html/Tools/MyDay.html b/share/html/Tools/MyDay.html
index 87e840e..442898c 100644
--- a/share/html/Tools/MyDay.html
+++ b/share/html/Tools/MyDay.html
@@ -64,7 +64,7 @@ href="<%RT->Config->Get('WebPath')%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$
 <td rowspan="2"><span class="label"><&|/l&>Comments</&>:<br /></span><textarea name="UpdateContent-<%$Ticket->Id%>" rows="5"
 cols="60"></textarea></td></tr>
 <tr <%$class|n%>>
-<td><span class="label"><&|/l&>Status</&>:</span> <& /Elements/SelectStatus, Name=> 'UpdateStatus-'.$Ticket->Id, 
+<td><span class="label"><&|/l&>Status</&>:</span> <& /Elements/SelectStatus, Name=> 'UpdateStatus-'.$Ticket->Id, TicketObj => $Ticket, 
 				  DefaultLabel => loc("[_1] (Unchanged)",loc($Ticket->Status())) &></td>
                   </tr>
 
diff --git a/share/html/m/ticket/create b/share/html/m/ticket/create
index cded94f..4ce94ce 100644
--- a/share/html/m/ticket/create
+++ b/share/html/m/ticket/create
@@ -289,9 +289,9 @@ $showrows->(
         $m->scomp(
         "/Elements/SelectStatus",
         Name         => "Status",
-        Default      => $ARGS{Status} || 'new',
+        QueueObj     => $QueueObj,
+        Default      => $ARGS{Status} || $QueueObj->Lifecycle->DefaultInitial,
         DefaultValue => 0,
-        SkipDeleted  => 1
         ),
 
     loc("Owner") =>
diff --git a/share/html/m/ticket/reply b/share/html/m/ticket/reply
index 4565de0..f7b01cd 100644
--- a/share/html/m/ticket/reply
+++ b/share/html/m/ticket/reply
@@ -57,7 +57,7 @@
 
 <div class="entry"><span class="label"><&|/l&>Status</&>:</span>
 <div class="value">
-<& /Elements/SelectStatus, Name=>"Status", DefaultLabel => loc("[_1] (Unchanged)", loc($t->Status)), Default => $ARGS{'Status'} || ($t->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
+<& /Elements/SelectStatus, Name=>"Status", TicketObj => $t, DefaultLabel => loc("[_1] (Unchanged)", loc($t->Status)), Default => $ARGS{'Status'} || ($t->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
 </div></div>
 
 <div class="entry"><span class="label"><&|/l&>Owner</&>:</span>

commit 7208c7a2a82798ff903e36a5d7f3675101c6a3d0
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Nov 12 12:01:49 2010 +0300

    improve tests

diff --git a/t/lifecycles/basics.t b/t/lifecycles/basics.t
index 2bf3c46..2f3d55a 100644
--- a/t/lifecycles/basics.t
+++ b/t/lifecycles/basics.t
@@ -23,9 +23,47 @@ diag "check basic API";
     my $schema = $general->Lifecycle;
     isa_ok($schema, 'RT::Lifecycle');
     is $schema->Name, 'default', "it's a default schema";
-    is join(', ', sort $schema->Valid),
-        join(', ', sort qw(new open stalled resolved rejected deleted)),
+    is_deeply [$schema->Valid],
+        [qw(new open stalled resolved rejected deleted)],
         'this is the default set from our config file';
+
+    foreach my $s ( qw(new open stalled resolved rejected deleted) ) {
+        ok $schema->IsValid($s), "valid";
+    }
+    ok !$schema->IsValid(), 'invalid';
+    ok !$schema->IsValid(''), 'invalid';
+    ok !$schema->IsValid(undef), 'invalid';
+    ok !$schema->IsValid('foo'), 'invalid';
+
+    is_deeply [$schema->Initial], ['new'], 'initial set';
+    ok $schema->IsInitial('new'), "initial";
+    ok !$schema->IsInitial('open'), "not initial";
+    ok !$schema->IsInitial, "not initial";
+    ok !$schema->IsInitial(''), "not initial";
+    ok !$schema->IsInitial(undef), "not initial";
+    ok !$schema->IsInitial('foo'), "not initial";
+
+    is_deeply [$schema->Active], [qw(open stalled)], 'active set';
+    ok( $schema->IsActive($_), "active" )
+        foreach qw(open stalled);
+    ok !$schema->IsActive('new'), "not active";
+    ok !$schema->IsActive, "not active";
+    ok !$schema->IsActive(''), "not active";
+    ok !$schema->IsActive(undef), "not active";
+    ok !$schema->IsActive('foo'), "not active";
+
+    is_deeply [$schema->Inactive], [qw(resolved rejected deleted)], 'inactive set';
+    ok( $schema->IsInactive($_), "inactive" )
+        foreach qw(resolved rejected deleted);
+    ok !$schema->IsInactive('new'), "not inactive";
+    ok !$schema->IsInactive, "not inactive";
+    ok !$schema->IsInactive(''), "not inactive";
+    ok !$schema->IsInactive(undef), "not inactive";
+    ok !$schema->IsInactive('foo'), "not inactive";
+
+    is_deeply [$schema->Transitions('')], [qw(new open resolved)], 'on create transitions';
+    ok $schema->IsTransition('' => $_), 'good transition'
+        foreach qw(new open resolved);
 }
 
 my ($baseurl, $m) = RT::Test->started_ok;

commit 7c1bd27fc16c6817b36a076ed7a5910ccd63ab6d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 13:41:35 2010 +0300

    add Lifecycle column to queues

diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index 93d1660..9d3868c 100755
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -27,6 +27,7 @@ CREATE TABLE Queues (
 	Description 		VARCHAR2(255),
 	CorrespondAddress 	VARCHAR2(120),
 	CommentAddress 		VARCHAR2(120),
+	Lifecycle 		VARCHAR2(32),
 	InitialPriority 	NUMBER(11,0) DEFAULT 0 NOT NULL,
 	FinalPriority 		NUMBER(11,0) DEFAULT 0 NOT NULL,
 	DefaultDueIn 		NUMBER(11,0) DEFAULT 0 NOT NULL,
diff --git a/etc/schema.Pg b/etc/schema.Pg
index c6bd1af..c39adfa 100755
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -50,6 +50,7 @@ CREATE TABLE Queues (
   Description varchar(255) NULL  ,
   CorrespondAddress varchar(120) NULL  ,
   CommentAddress varchar(120) NULL  ,
+  Lifecycle varchar(32) NULL,
   InitialPriority integer NOT NULL DEFAULT 0  ,
   FinalPriority integer NOT NULL DEFAULT 0  ,
   DefaultDueIn integer NOT NULL DEFAULT 0  ,
diff --git a/etc/schema.SQLite b/etc/schema.SQLite
index 40367de..4028248 100755
--- a/etc/schema.SQLite
+++ b/etc/schema.SQLite
@@ -28,6 +28,7 @@ CREATE TABLE Queues (
   Description varchar(255) NULL  ,
   CorrespondAddress varchar(120) NULL  ,
   CommentAddress varchar(120) NULL  ,
+  Lifecycle varchar(32) NULL  ,
   InitialPriority integer NULL  ,
   FinalPriority integer NULL  ,
   DefaultDueIn integer NULL  ,
diff --git a/etc/schema.mysql b/etc/schema.mysql
index dcaa500..112382a 100755
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@ -24,6 +24,7 @@ CREATE TABLE Queues (
   Description varchar(255) NULL  ,
   CorrespondAddress varchar(120) CHARACTER SET ascii NULL,
   CommentAddress varchar(120) CHARACTER SET ascii NULL,
+  Lifecycle varchar(32) CHARACTER SET ascii NULL,
   InitialPriority integer NOT NULL DEFAULT 0  ,
   FinalPriority integer NOT NULL DEFAULT 0  ,
   DefaultDueIn integer NOT NULL DEFAULT 0  ,

commit 568ebd303f9ed4cdb620b7bb0ef835158beb26cd
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 13:41:58 2010 +0300

    schema upgrade bits for lifecycle column

diff --git a/etc/upgrade/3.9.6/schema.Oracle b/etc/upgrade/3.9.6/schema.Oracle
index 6ccf138..f33468b 100644
--- a/etc/upgrade/3.9.6/schema.Oracle
+++ b/etc/upgrade/3.9.6/schema.Oracle
@@ -1 +1,2 @@
 ALTER TABLE Tickets MODIFY ( Status TYPE VARCHAR2(64) );
+ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR2(32) NULL;
diff --git a/etc/upgrade/3.9.6/schema.Pg b/etc/upgrade/3.9.6/schema.Pg
index f4f909e..77658f7 100644
--- a/etc/upgrade/3.9.6/schema.Pg
+++ b/etc/upgrade/3.9.6/schema.Pg
@@ -1 +1,2 @@
 ALTER TABLE Tickets ALTER Status TYPE varchar(64);
+ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL;
diff --git a/etc/upgrade/3.9.6/schema.SQLite b/etc/upgrade/3.9.6/schema.SQLite
index 9d02d49..26ac95e 100644
--- a/etc/upgrade/3.9.6/schema.SQLite
+++ b/etc/upgrade/3.9.6/schema.SQLite
@@ -68,3 +68,4 @@ INSERT INTO Tickets SELECT * FROM Tickets_backup;
 DROP TABLE Tickets_backup;
 COMMIT;
 
+ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL;
diff --git a/etc/upgrade/3.9.6/schema.mysql b/etc/upgrade/3.9.6/schema.mysql
index b0a9eaf..dbc3861 100644
--- a/etc/upgrade/3.9.6/schema.mysql
+++ b/etc/upgrade/3.9.6/schema.mysql
@@ -1 +1,2 @@
 ALTER TABLE Tickets Modify Status varchar(64);
+ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL;

commit 6d9d2b0e0576507e761c6e4f235744c6604c33cf
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 13:53:56 2010 +0300

    generate new Queue.pm using factory

diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 9b02c7a..6b19ef5 100755
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -90,6 +90,7 @@ Create takes a hash of values and creates a row in the database:
   varchar(255) 'Description'.
   varchar(120) 'CorrespondAddress'.
   varchar(120) 'CommentAddress'.
+  varchar(32) 'Lifecycle'.
   int(11) 'InitialPriority'.
   int(11) 'FinalPriority'.
   int(11) 'DefaultDueIn'.
@@ -107,6 +108,7 @@ sub Create {
                 Description => '',
                 CorrespondAddress => '',
                 CommentAddress => '',
+                Lifecycle => '',
                 InitialPriority => '0',
                 FinalPriority => '0',
                 DefaultDueIn => '0',
@@ -118,6 +120,7 @@ sub Create {
                          Description => $args{'Description'},
                          CorrespondAddress => $args{'CorrespondAddress'},
                          CommentAddress => $args{'CommentAddress'},
+                         Lifecycle => $args{'Lifecycle'},
                          InitialPriority => $args{'InitialPriority'},
                          FinalPriority => $args{'FinalPriority'},
                          DefaultDueIn => $args{'DefaultDueIn'},
@@ -209,6 +212,24 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
+=head2 Lifecycle
+
+Returns the current value of Lifecycle. 
+(In the database, Lifecycle is stored as varchar(32).)
+
+
+
+=head2 SetLifecycle VALUE
+
+
+Set Lifecycle to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Lifecycle will be stored as a varchar(32).)
+
+
+=cut
+
+
 =head2 InitialPriority
 
 Returns the current value of InitialPriority. 
@@ -331,6 +352,8 @@ sub _CoreAccessible {
 		{read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
         CommentAddress => 
 		{read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
+        Lifecycle => 
+		{read => 1, write => 1, sql_type => 12, length => 32,  is_blob => 0,  is_numeric => 0,  type => 'varchar(32)', default => ''},
         InitialPriority => 
 		{read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         FinalPriority => 

commit fbc20bb904d0de51ab1b0e263d1ebd21269c7b41
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 13:56:42 2010 +0300

    don't use %LifecycleMap in tests

diff --git a/t/lifecycles/utils.pl b/t/lifecycles/utils.pl
index 19daf17..0146566 100644
--- a/t/lifecycles/utils.pl
+++ b/t/lifecycles/utils.pl
@@ -58,7 +58,6 @@ Set(\%Lifecycles,
         },
     },
 );
-Set(\%LifecycleMap, delivery => 'delivery');
 END
 }
 

commit 4e6fb09a48d01818f830d2e344cfeda07f083c8c
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 13:58:59 2010 +0300

    set lifecycle during create

diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index 3f74a1f..edb6eda 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -13,6 +13,7 @@ ok $general && $general->id, 'loaded or created a queue';
 
 my $delivery = RT::Test->load_or_create_queue(
     Name => 'delivery',
+    Lifecycle => 'delivery',
 );
 ok $delivery && $delivery->id, 'loaded or created a queue';
 

commit 9577737d16308e47331bd3bff29207d01b342137
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 16:02:22 2010 +0300

    Lifecycle value from DB column

diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index d662636..2a321da 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -66,6 +66,7 @@ An RT queue object.
 package RT::Queue;
 
 use strict;
+use warnings;
 no warnings qw(redefine);
 
 use RT::Groups;
@@ -157,6 +158,7 @@ $RT::ACE::OBJECT_TYPES{'RT::Queue'} = 1;
 
 __PACKAGE__->AddRights(%$RIGHTS);
 __PACKAGE__->AddRightCategories(%$RIGHT_CATEGORIES);
+require RT::Lifecycle;
 
 =head2 AddRights C<RIGHT>, C<DESCRIPTION> [, ...]
 
@@ -242,28 +244,50 @@ sub RightCategories {
 }
 
 
-
 sub Lifecycle {
     my $self = shift;
     unless (ref $self && $self->id) { 
         return RT::Lifecycle->Load('')
     }
 
-    my $name = '';
+    my $name = $self->_Value( Lifecycle => @_ );
+    $name ||= 'default';
 
-    # If you don't have Lifecycles set, name is default
-    my $lifecycles = RT->Config->Get('LifecycleMap');
-    if ($lifecycles && $self->Name && defined $lifecycles->{$self->Name}) {
-        $name = $lifecycles->{$self->Name};
+    my $res = RT::Lifecycle->Load( $name );
+    $RT::Logger->error("Lifecycle '$name' for queue '".$self->Name."' doesn't exist")
+        unless $res;
+    return $res;
+}
+
+sub SetLifecycle {
+    my $self = shift;
+    my $value = shift;
+
+    if ( $value && $value ne 'default' ) {
+        return (0, $self->loc('[_1] is not valid lifecycle', $value ))
+            unless $self->ValidateLifecycle( $value );
     } else {
-        $name = 'default';
+        $value = undef;
     }
 
-    my $res = RT::Lifecycle->Load( $name );
-    $RT::Logger->error("Lifecycle '$name' for queue '".$self->Name."' doesn't exist") unless $res;
-    return $res;
+    return $self->_Set( Field => 'Lifecycle', Value => $value, @_ );
 }
 
+=head2 ValidateLifecycle NAME
+
+Takes a lifecycle name. Returns true if it's an ok name and such
+lifecycle is configured. Returns undef otherwise.
+
+=cut
+
+sub ValidateLifecycle {
+    my $self = shift;
+    my $value = shift;
+    return undef unless RT::Lifecycle->Load( $value );
+    return 1;
+}
+
+
 =head2 ActiveStatusArray
 
 Returns an array of all ActiveStatuses for this queue
@@ -359,9 +383,10 @@ sub Create {
     my $self = shift;
     my %args = (
         Name              => undef,
-        CorrespondAddress => '',
         Description       => '',
+        CorrespondAddress => '',
         CommentAddress    => '',
+        Lifecycle         => 'default',
         SubjectTag        => '',
         InitialPriority   => 0,
         FinalPriority     => 0,
@@ -381,6 +406,13 @@ sub Create {
         return ( 0, $self->loc('Queue already exists') );
     }
 
+    if ( $args{'Lifecycle'} && $args{'Lifecycle'} ne 'default' ) {
+        return ( 0, $self->loc('Invalid lifecycle name') )
+            unless $self->ValidateLifecycle( $args{'Lifecycle'} );
+    } else {
+        $args{'Lifecycle'} = undef;
+    }
+
     my %attrs = map {$_ => 1} $self->ReadableAttributes;
 
     #TODO better input validation

commit c956650023092575295a726fb0237aac507d0180
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 16:03:13 2010 +0300

    drop LifecycleMap option from the config

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index db9ea1e..cec8484 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -2026,30 +2026,6 @@ Set(%Lifecycles,
     },
 );
 
-
-
-=item %LifecycleMap
-
-LifecycleMap maps lifecycles to individual queues.
-
-If there is no record for a given queue then RT uses the
-B<default> lifecycle
-
-For example:
-
-    Set( %LifecycleMap,
-        General => 'some_lifecycle',
-        'Another Queue' => 'another_lifecycle',
-    );
-
-=cut
-
-
-Set( %LifecycleMap,
-     General => 'default',
-);
-
-
 =head1 Ticket Relationships
 
 =item C<$LinkTransactionsRun1Scrip>

commit 57a87f2f34ae50cda33d0924bb0cc549378486ac
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 16:07:55 2010 +0300

    set proper lifecycle in the test

diff --git a/t/lifecycles/moving.t b/t/lifecycles/moving.t
index 730b6e8..6e0d64b 100644
--- a/t/lifecycles/moving.t
+++ b/t/lifecycles/moving.t
@@ -13,6 +13,7 @@ ok $general && $general->id, 'loaded or created a queue';
 
 my $delivery = RT::Test->load_or_create_queue(
     Name => 'delivery',
+    Lifecycle => 'delivery',
 );
 ok $delivery && $delivery->id, 'loaded or created a queue';
 

commit 875a7e15b20df188eb110ee8215e8e8a7886a4f8
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 16:23:24 2010 +0300

    drop "exit;" somebody left in the test

diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index edb6eda..1ee419c 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -144,7 +144,6 @@ diag "dates on create for delivery schema";
         ok $ticket->StartedObj->Unix > 0, 'started is set to ' .$ticket->StartedObj->AsString ;
         is $ticket->ResolvedObj->Unix, 0, 'resolved is not set';
     }
-    exit;
     {
         my $ticket = RT::Ticket->new( RT->SystemUser );
         my ($id, $msg) = $ticket->Create(

commit cf6185ea1e9c4f40b4f8d9c9f10810656016b5ba
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 16:24:05 2010 +0300

    fix typo in status name

diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index 1ee419c..397c561 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -202,7 +202,7 @@ diag "dates on create for delivery schema";
         ok $id, 'created a ticket';
         my ($statusval,$statusmsg) = $ticket->SetStatus('on way');
         ok($statusval,$statusmsg);
-        ($statusval,$statusmsg) = $ticket->SetStatus('delievered');
+        ($statusval,$statusmsg) = $ticket->SetStatus('delivered');
         ok($statusval,$statusmsg);
         is $ticket->StartedObj->ISO, $test_date, 'started is set';
         is $ticket->ResolvedObj->ISO, $test_date, 'resolved is set';

commit 022930e7240c8116e49fb14962dbc59f78be3b07
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Nov 15 16:24:43 2010 +0300

    mark test as todo

diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index 397c561..d8a27f6 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -205,7 +205,10 @@ diag "dates on create for delivery schema";
         ($statusval,$statusmsg) = $ticket->SetStatus('delivered');
         ok($statusval,$statusmsg);
         is $ticket->StartedObj->ISO, $test_date, 'started is set';
-        is $ticket->ResolvedObj->ISO, $test_date, 'resolved is set';
+        TODO: {
+            local $TODO = "we should decide if we set resolved repeatedly";
+            is $ticket->ResolvedObj->ISO, $test_date, 'resolved is set';
+        };
     }
 }
 

-----------------------------------------------------------------------


More information about the Rt-commit mailing list