rt 4.2.14 (#13852)
[freeside.git] / rt / lib / RT / Record / Role / Lifecycle.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2 #
3 # COPYRIGHT:
4 #
5 # This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
6 #                                          <sales@bestpractical.com>
7 #
8 # (Except where explicitly superseded by other copyright notices)
9 #
10 #
11 # LICENSE:
12 #
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
16 # from www.gnu.org.
17 #
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 # General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301 or visit their web page on the internet at
27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 #
29 #
30 # CONTRIBUTION SUBMISSION POLICY:
31 #
32 # (The following paragraph is not intended to limit the rights granted
33 # to you to modify and distribute this software under the terms of
34 # the GNU General Public License and is only of importance to you if
35 # you choose to contribute your changes and enhancements to the
36 # community by submitting them to Best Practical Solutions, LLC.)
37 #
38 # By intentionally submitting any modifications, corrections or
39 # derivatives to this work, or any other work intended for use with
40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 # you are the copyright holder for those contributions and you grant
42 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 # royalty-free, perpetual, license to use, copy, create derivative
44 # works based on those contributions, and sublicense and distribute
45 # those contributions and any derivatives thereof.
46 #
47 # END BPS TAGGED BLOCK }}}
48
49 use strict;
50 use warnings;
51
52 package RT::Record::Role::Lifecycle;
53 use Role::Basic;
54 use Scalar::Util qw(blessed);
55
56 =head1 NAME
57
58 RT::Record::Role::Lifecycle - Common methods for records which have a Lifecycle column
59
60 =head1 REQUIRES
61
62 =head2 L<RT::Record::Role>
63
64 =head2 LifecycleType
65
66 Used as a role parameter.  Must return a string of the type of lifecycles the
67 record consumes, i.e.  I<ticket> for L<RT::Queue>.
68
69 =head2 Lifecycle
70
71 A Lifecycle method which returns a lifecycle name is required.  Currently
72 unenforced at compile-time due to poor interactions with
73 L<DBIx::SearchBuilder::Record/AUTOLOAD>.  You'll hit run-time errors if this
74 method isn't available in consuming classes, however.
75
76 =cut
77
78 with 'RT::Record::Role';
79 requires 'LifecycleType';
80
81 # XXX: can't require column methods due to DBIx::SB::Record's AUTOLOAD
82 #requires 'Lifecycle';
83
84 =head1 PROVIDES
85
86 =head2 LifecycleObj
87
88 Returns an L<RT::Lifecycle> object for this record's C<Lifecycle>.  If called
89 as a class method, returns an L<RT::Lifecycle> object which is an aggregation
90 of all lifecycles of the appropriate type.
91
92 =cut
93
94 sub LifecycleObj {
95     my $self = shift;
96     my $type = $self->LifecycleType;
97     my $fallback = $self->_Accessible( Lifecycle => "default" );
98
99     unless (blessed($self) and $self->id) {
100         return RT::Lifecycle->Load( Type => $type );
101     }
102
103     my $name = $self->Lifecycle || $fallback;
104     my $res  = RT::Lifecycle->Load( Name => $name, Type => $type );
105     unless ( $res ) {
106         RT->Logger->error(
107             sprintf "Lifecycle '%s' of type %s for %s #%d doesn't exist",
108                     $name, $type, ref($self), $self->id);
109         return RT::Lifecycle->Load( Name => $fallback, Type => $type );
110     }
111     return $res;
112 }
113
114 =head2 SetLifecycle
115
116 Validates that the specified lifecycle exists before updating the record.
117
118 Takes a lifecycle name.
119
120 =cut
121
122 sub SetLifecycle {
123     my $self  = shift;
124     my $value = shift || $self->_Accessible( Lifecycle => "default" );
125
126     return (0, $self->loc('[_1] is not a valid lifecycle', $value))
127         unless $self->ValidateLifecycle($value);
128
129     return $self->_Set( Field => 'Lifecycle', Value => $value, @_ );
130 }
131
132 =head2 ValidateLifecycle
133
134 Takes a lifecycle name.  Returns true if it's an OK name and such lifecycle is
135 configured.  Returns false otherwise.
136
137 =cut
138
139 sub ValidateLifecycle {
140     my $self  = shift;
141     my $value = shift;
142     return unless $value;
143     return unless RT::Lifecycle->Load( Name => $value, Type => $self->LifecycleType );
144     return 1;
145 }
146
147 =head2 ActiveStatusArray
148
149 Returns an array of all ActiveStatuses for the lifecycle
150
151 =cut
152
153 sub ActiveStatusArray {
154     my $self = shift;
155     return $self->LifecycleObj->Valid('initial', 'active');
156 }
157
158 =head2 InactiveStatusArray
159
160 Returns an array of all InactiveStatuses for the lifecycle
161
162 =cut
163
164 sub InactiveStatusArray {
165     my $self = shift;
166     return $self->LifecycleObj->Inactive;
167 }
168
169 =head2 StatusArray
170
171 Returns an array of all statuses for the lifecycle
172
173 =cut
174
175 sub StatusArray {
176     my $self = shift;
177     return $self->LifecycleObj->Valid( @_ );
178 }
179
180 =head2 IsValidStatus
181
182 Takes a status.
183
184 Returns true if STATUS is a valid status.  Otherwise, returns 0.
185
186 =cut
187
188 sub IsValidStatus {
189     my $self  = shift;
190     return $self->LifecycleObj->IsValid( shift );
191 }
192
193 =head2 IsActiveStatus
194
195 Takes a status.
196
197 Returns true if STATUS is a Active status.  Otherwise, returns 0
198
199 =cut
200
201 sub IsActiveStatus {
202     my $self  = shift;
203     return $self->LifecycleObj->IsValid( shift, 'initial', 'active');
204 }
205
206 =head2 IsInactiveStatus
207
208 Takes a status.
209
210 Returns true if STATUS is a Inactive status.  Otherwise, returns 0
211
212 =cut
213
214 sub IsInactiveStatus {
215     my $self  = shift;
216     return $self->LifecycleObj->IsInactive( shift );
217 }
218
219 1;