rt 4.0.23
[freeside.git] / rt / lib / RT / Condition / StatusChange.pm
index 902bf2a..668c5bc 100644 (file)
@@ -1,38 +1,40 @@
 # BEGIN BPS TAGGED BLOCK {{{
-# 
+#
 # COPYRIGHT:
-#  
-# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC 
-#                                          <jesse@bestpractical.com>
-# 
+#
+# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
 # (Except where explicitly superseded by other copyright notices)
-# 
-# 
+#
+#
 # LICENSE:
-# 
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-# 
-# 
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
 # CONTRIBUTION SUBMISSION POLICY:
-# 
+#
 # (The following paragraph is not intended to limit the rights granted
 # to you to modify and distribute this software under the terms of
 # the GNU General Public License and is only of importance to you if
 # you choose to contribute your changes and enhancements to the
 # community by submitting them to Best Practical Solutions, LLC.)
-# 
+#
 # By intentionally submitting any modifications, corrections or
 # derivatives to this work, or any other work intended for use with
 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
 # royalty-free, perpetual, license to use, copy, create derivative
 # works based on those contributions, and sublicense and distribute
 # those contributions and any derivatives thereof.
-# 
+#
 # END BPS TAGGED BLOCK }}}
-
 
 package RT::Condition::StatusChange;
-require RT::Condition::Generic;
-
+use base 'RT::Condition';
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Condition::Generic);
+use warnings;
+
+=head2 DESCRIPTION
+
+This condition check passes if the current transaction is a status change.
+
+The argument can be used to apply additional conditions on old and new values.
+
+If argument is empty then the check passes for any change of the status field.
+
+If argument is equal to new value then check is passed. This is behavior
+is close to RT 3.8 and older. For example, setting the argument to 'resolved' means
+'fire scrip when status changed from any to resolved'.
+
+The following extended format is supported:
+
+    old: comma separated list; new: comma separated list
+
+For example:
+
+    old: open; new: resolved
+
+You can omit old or new part, for example:
+
+    old: open
 
+    new: resolved
 
-=head2 IsApplicable
+You can specify multiple values, for example:
 
-If the argument passed in is equivalent to the new value of
-the Status Obj
+    old: new, open; new: resolved, rejected
+
+Status sets ('initial', 'active' or 'inactive') can be used, for example:
+
+    old: active; new: inactive
+
+    old: initial, active; new: resolved
 
 =cut
 
 sub IsApplicable {
     my $self = shift;
-    if (($self->TransactionObj->Field eq 'Status') and 
-    ($self->Argument eq $self->TransactionObj->NewValue())) {
-       return(1);
-    } 
+    my $txn = $self->TransactionObj;
+    my ($type, $field) = ($txn->Type, $txn->Field);
+    return 0 unless $type eq 'Status' || ($type eq 'Set' && $field eq 'Status');
+
+    my $argument = $self->Argument;
+    return 1 unless $argument;
+
+    my $new = $txn->NewValue || '';
+    return 1 if $argument eq $new;
+
+    # let's parse argument
+    my ($old_must_be, $new_must_be) = ('', '');
+    if ( $argument =~ /^\s*old:\s*(.*);\s*new:\s*(.*)\s*$/i ) {
+        ($old_must_be, $new_must_be) = ($1, $2);
+    }
+    elsif ( $argument =~ /^\s*new:\s*(.*)\s*$/i ) {
+        $new_must_be = $1;
+    }
+    elsif ( $argument =~ /^\s*old:\s*(.*)\s*$/i ) {
+        $old_must_be = $1;
+    }
     else {
-       return(undef);
+        $RT::Logger->error("Argument '$argument' is incorrect.")
+            unless RT::Lifecycle->Load('')->IsValid( $argument );
+        return 0;
+    }
+
+    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 $_): $_ }
+            grep defined && length,
+            map { s/^\s+//; s/\s+$//; $_ }
+            split /,/, $new_must_be;
+    }
+    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 $_): $_ }
+            grep defined && length,
+            map { s/^\s+//; s/\s+$//; $_ }
+            split /,/, $old_must_be;
     }
+    return 1;
 }
 
-eval "require RT::Condition::StatusChange_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/StatusChange_Vendor.pm});
-eval "require RT::Condition::StatusChange_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/StatusChange_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;