Putting 4.2.0 on top of 4.0.17
[usit-rt.git] / lib / RT / Scrip.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2 #
3 # COPYRIGHT:
4 #
5 # This software is Copyright (c) 1996-2013 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 =head1 NAME
50
51   RT::Scrip - an RT Scrip object
52
53 =head1 SYNOPSIS
54
55   use RT::Scrip;
56
57 =head1 DESCRIPTION
58
59
60 =head1 METHODS
61
62
63 =cut
64
65
66 package RT::Scrip;
67
68 use strict;
69 use warnings;
70 use base 'RT::Record';
71
72 use RT::Queue;
73 use RT::Template;
74 use RT::ScripCondition;
75 use RT::ScripAction;
76 use RT::Scrips;
77 use RT::ObjectScrip;
78
79 sub Table {'Scrips'}
80
81 # {{{ sub Create
82
83 =head2 Create
84
85 Creates a new entry in the Scrips table. Takes a paramhash with:
86
87         Queue                  => 0,
88         Description            => undef,
89         Template               => undef,
90         ScripAction            => undef,
91         ScripCondition         => undef,
92         CustomPrepareCode      => undef,
93         CustomCommitCode       => undef,
94         CustomIsApplicableCode => undef,
95
96
97
98
99 Returns (retval, msg);
100 retval is 0 for failure or scrip id.  msg is a textual description of what happened.
101
102 =cut
103
104 sub Create {
105     my $self = shift;
106     my %args = (
107         Queue                  => 0,
108         Template               => undef,                 # name or id
109         ScripAction            => 0,                     # name or id
110         ScripCondition         => 0,                     # name or id
111         Stage                  => 'TransactionCreate',
112         Description            => undef,
113         CustomPrepareCode      => undef,
114         CustomCommitCode       => undef,
115         CustomIsApplicableCode => undef,
116         @_
117     );
118
119     if ($args{CustomPrepareCode} || $args{CustomCommitCode} || $args{CustomIsApplicableCode}) {
120         unless ( $self->CurrentUser->HasRight( Object => $RT::System,
121                                                Right  => 'ExecuteCode' ) )
122         {
123             return ( 0, $self->loc('Permission Denied') );
124         }
125     }
126
127     unless ( $args{'Queue'} ) {
128         unless ( $self->CurrentUser->HasRight( Object => $RT::System,
129                                                Right  => 'ModifyScrips' ) )
130         {
131             return ( 0, $self->loc('Permission Denied') );
132         }
133         $args{'Queue'} = 0;    # avoid undef sneaking in
134     }
135     else {
136         my $QueueObj = RT::Queue->new( $self->CurrentUser );
137         $QueueObj->Load( $args{'Queue'} );
138         unless ( $QueueObj->id ) {
139             return ( 0, $self->loc('Invalid queue') );
140         }
141         unless ( $QueueObj->CurrentUserHasRight('ModifyScrips') ) {
142             return ( 0, $self->loc('Permission Denied') );
143         }
144         $args{'Queue'} = $QueueObj->id;
145     }
146
147     #TODO +++ validate input
148
149     return ( 0, $self->loc("Action is mandatory argument") )
150         unless $args{'ScripAction'};
151     my $action = RT::ScripAction->new( $self->CurrentUser );
152     $action->Load( $args{'ScripAction'} );
153     return ( 0, $self->loc( "Action '[_1]' not found", $args{'ScripAction'} ) ) 
154         unless $action->Id;
155
156     return ( 0, $self->loc("Template is mandatory argument") )
157         unless $args{'Template'};
158     my $template = RT::Template->new( $self->CurrentUser );
159     if ( $args{'Template'} =~ /\D/ ) {
160         $template->LoadByName( Name => $args{'Template'}, Queue => $args{'Queue'} );
161         return ( 0, $self->loc( "Global template '[_1]' not found", $args{'Template'} ) )
162             if !$template->Id && !$args{'Queue'};
163         return ( 0, $self->loc( "Global or queue specific template '[_1]' not found", $args{'Template'} ) )
164             if !$template->Id;
165     } else {
166         $template->Load( $args{'Template'} );
167         return ( 0, $self->loc( "Template '[_1]' not found", $args{'Template'} ) )
168             unless $template->Id;
169
170         return (0, $self->loc( "Template '[_1]' is not global" ))
171             if !$args{'Queue'} && $template->Queue;
172         return (0, $self->loc( "Template '[_1]' is not global nor queue specific" ))
173             if $args{'Queue'} && $template->Queue && $template->Queue != $args{'Queue'};
174     }
175
176     return ( 0, $self->loc("Condition is mandatory argument") )
177         unless $args{'ScripCondition'};
178     my $condition = RT::ScripCondition->new( $self->CurrentUser );
179     $condition->Load( $args{'ScripCondition'} );
180     return ( 0, $self->loc( "Condition '[_1]' not found", $args{'ScripCondition'} ) )
181         unless $condition->Id;
182
183     if ( $args{'Stage'} eq 'Disabled' ) {
184         $RT::Logger->warning("Disabled Stage is deprecated");
185         $args{'Stage'} = 'TransactionCreate';
186         $args{'Disabled'} = 1;
187     }
188     $args{'Disabled'} ||= 0;
189
190     my ( $id, $msg ) = $self->SUPER::Create(
191         Template               => $template->Name,
192         ScripCondition         => $condition->id,
193         ScripAction            => $action->Id,
194         Disabled               => $args{'Disabled'},
195         Description            => $args{'Description'},
196         CustomPrepareCode      => $args{'CustomPrepareCode'},
197         CustomCommitCode       => $args{'CustomCommitCode'},
198         CustomIsApplicableCode => $args{'CustomIsApplicableCode'},
199     );
200     return ( $id, $msg ) unless $id;
201
202     (my $status, $msg) = RT::ObjectScrip->new( $self->CurrentUser )->Add(
203         Scrip    => $self,
204         Stage    => $args{'Stage'},
205         ObjectId => $args{'Queue'},
206     );
207     $RT::Logger->error( "Couldn't add scrip: $msg" ) unless $status;
208
209     return ( $id, $self->loc('Scrip Created') );
210 }
211
212
213
214 =head2 Delete
215
216 Delete this object
217
218 =cut
219
220 sub Delete {
221     my $self = shift;
222
223     unless ( $self->CurrentUserHasRight('ModifyScrips') ) {
224         return ( 0, $self->loc('Permission Denied') );
225     }
226
227     RT::ObjectScrip->new( $self->CurrentUser )->DeleteAll( Scrip => $self );
228
229     return ( $self->SUPER::Delete(@_) );
230 }
231
232 sub IsGlobal { return shift->IsAdded(0) }
233
234 sub IsAdded {
235     my $self = shift;
236     my $record = RT::ObjectScrip->new( $self->CurrentUser );
237     $record->LoadByCols( Scrip => $self->id, ObjectId => shift || 0 );
238     return undef unless $record->id;
239     return $record;
240 }
241
242 sub IsAddedToAny {
243     my $self = shift;
244     my $record = RT::ObjectScrip->new( $self->CurrentUser );
245     $record->LoadByCols( Scrip => $self->id );
246     return $record->id ? 1 : 0;
247 }
248
249 sub AddedTo {
250     my $self = shift;
251     return RT::ObjectScrip->new( $self->CurrentUser )
252         ->AddedTo( Scrip => $self );
253 }
254
255 sub NotAddedTo {
256     my $self = shift;
257     return RT::ObjectScrip->new( $self->CurrentUser )
258         ->NotAddedTo( Scrip => $self );
259 }
260
261 sub AddToObject {
262     my $self = shift;
263     my %args = @_%2? (ObjectId => @_) : (@_);
264
265     my $queue;
266     if ( $args{'ObjectId'} ) {
267         $queue = RT::Queue->new( $self->CurrentUser );
268         $queue->Load( $args{'ObjectId'} );
269         return (0, $self->loc('Invalid queue'))
270             unless $queue->id;
271
272         $args{'ObjectId'} = $queue->id;
273     }
274     return ( 0, $self->loc('Permission Denied') )
275         unless $self->CurrentUser->PrincipalObj->HasRight(
276             Object => $queue || $RT::System, Right => 'ModifyScrips',
277         )
278     ;
279
280     my $tname = $self->Template;
281     my $template = RT::Template->new( $self->CurrentUser );
282     $template->LoadByName( Queue => $queue? $queue->id : 0, Name => $tname );
283     unless ( $template->id ) {
284         if ( $queue ) {
285             return (0, $self->loc('No template [_1] in queue [_2] or global',
286                     $tname, $queue->Name||$queue->id));
287         } else {
288             return (0, $self->loc('No global template [_1]', $tname));
289         }
290     }
291
292     my $rec = RT::ObjectScrip->new( $self->CurrentUser );
293     return $rec->Add( %args, Scrip => $self );
294 }
295
296 sub RemoveFromObject {
297     my $self = shift;
298     my %args = @_%2? (ObjectId => @_) : (@_);
299
300     my $queue;
301     if ( $args{'ObjectId'} ) {
302         $queue = RT::Queue->new( $self->CurrentUser );
303         $queue->Load( $args{'ObjectId'} );
304         return (0, $self->loc('Invalid queue id'))
305             unless $queue->id;
306     }
307     return ( 0, $self->loc('Permission Denied') )
308         unless $self->CurrentUser->PrincipalObj->HasRight(
309             Object => $queue || $RT::System, Right => 'ModifyScrips',
310         )
311     ;
312
313     my $rec = RT::ObjectScrip->new( $self->CurrentUser );
314     $rec->LoadByCols( Scrip => $self->id, ObjectId => $args{'ObjectId'} );
315     return (0, $self->loc('Scrip is not added') ) unless $rec->id;
316     return $rec->Delete;
317 }
318
319 =head2 ActionObj
320
321 Retuns an RT::Action object with this Scrip's Action
322
323 =cut
324
325 sub ActionObj {
326     my $self = shift;
327
328     unless ( defined $self->{'ScripActionObj'} ) {
329         require RT::ScripAction;
330         $self->{'ScripActionObj'} = RT::ScripAction->new( $self->CurrentUser );
331         $self->{'ScripActionObj'}->Load( $self->ScripAction );
332     }
333     return ( $self->{'ScripActionObj'} );
334 }
335
336
337
338 =head2 ConditionObj
339
340 Retuns an L<RT::ScripCondition> object with this Scrip's IsApplicable
341
342 =cut
343
344 sub ConditionObj {
345     my $self = shift;
346
347     my $res = RT::ScripCondition->new( $self->CurrentUser );
348     $res->Load( $self->ScripCondition );
349     return $res;
350 }
351
352
353 =head2 LoadModules
354
355 Loads scrip's condition and action modules.
356
357 =cut
358
359 sub LoadModules {
360     my $self = shift;
361
362     $self->ConditionObj->LoadCondition;
363     $self->ActionObj->LoadAction;
364 }
365
366
367 =head2 TemplateObj
368
369 Retuns an RT::Template object with this Scrip's Template
370
371 =cut
372
373 sub TemplateObj {
374     my $self = shift;
375     my $queue = shift;
376
377     my $res = RT::Template->new( $self->CurrentUser );
378     $res->LoadByName( Queue => $queue, Name => $self->Template );
379     return $res;
380 }
381
382 =head2 Stage
383
384 Takes TicketObj named argument and returns scrip's stage when
385 added to ticket's queue.
386
387 =cut
388
389 sub Stage {
390     my $self = shift;
391     my %args = ( TicketObj => undef, @_ );
392
393     my $queue = $args{'TicketObj'}->Queue;
394     my $rec = RT::ObjectScrip->new( $self->CurrentUser );
395     $rec->LoadByCols( Scrip => $self->id, ObjectId => $queue );
396     return $rec->Stage if $rec->id;
397
398     $rec->LoadByCols( Scrip => $self->id, ObjectId => 0 );
399     return $rec->Stage if $rec->id;
400
401     return undef;
402 }
403
404
405 =head2 Apply { TicketObj => undef, TransactionObj => undef}
406
407 This method instantiates the ScripCondition and ScripAction objects for a
408 single execution of this scrip. it then calls the IsApplicable method of the 
409 ScripCondition.
410 If that succeeds, it calls the Prepare method of the
411 ScripAction. If that succeeds, it calls the Commit method of the ScripAction.
412
413 Usually, the ticket and transaction objects passed to this method
414 should be loaded by the SuperUser role
415
416 =cut
417
418
419 # XXX TODO : This code appears to be obsoleted in favor of similar code in Scrips->Apply.
420 # Why is this here? Is it still called?
421
422 sub Apply {
423     my $self = shift;
424     my %args = ( TicketObj      => undef,
425                  TransactionObj => undef,
426                  @_ );
427
428     $RT::Logger->debug("Now applying scrip ".$self->Id . " for transaction ".$args{'TransactionObj'}->id);
429
430     my $ApplicableTransactionObj = $self->IsApplicable( TicketObj      => $args{'TicketObj'},
431                                                         TransactionObj => $args{'TransactionObj'} );
432     unless ( $ApplicableTransactionObj ) {
433         return undef;
434     }
435
436     if ( $ApplicableTransactionObj->id != $args{'TransactionObj'}->id ) {
437         $RT::Logger->debug("Found an applicable transaction ".$ApplicableTransactionObj->Id . " in the same batch with transaction ".$args{'TransactionObj'}->id);
438     }
439
440     #If it's applicable, prepare and commit it
441     $RT::Logger->debug("Now preparing scrip ".$self->Id . " for transaction ".$ApplicableTransactionObj->id);
442     unless ( $self->Prepare( TicketObj      => $args{'TicketObj'},
443                              TransactionObj => $ApplicableTransactionObj )
444       ) {
445         return undef;
446     }
447
448     $RT::Logger->debug("Now commiting scrip ".$self->Id . " for transaction ".$ApplicableTransactionObj->id);
449     unless ( $self->Commit( TicketObj => $args{'TicketObj'},
450                             TransactionObj => $ApplicableTransactionObj)
451       ) {
452         return undef;
453     }
454
455     $RT::Logger->debug("We actually finished scrip ".$self->Id . " for transaction ".$ApplicableTransactionObj->id);
456     return (1);
457
458 }
459
460
461
462 =head2 IsApplicable
463
464 Calls the  Condition object's IsApplicable method
465
466 Upon success, returns the applicable Transaction object.
467 Otherwise, undef is returned.
468
469 If the Scrip is in the TransactionCreate Stage (the usual case), only test
470 the associated Transaction object to see if it is applicable.
471
472 For Scrips in the TransactionBatch Stage, test all Transaction objects
473 created during the Ticket object's lifetime, and returns the first one
474 that is applicable.
475
476 =cut
477
478 sub IsApplicable {
479     my $self = shift;
480     my %args = ( TicketObj      => undef,
481                  TransactionObj => undef,
482                  @_ );
483
484     my $return;
485     eval {
486
487         my @Transactions;
488
489         my $stage = $self->Stage( TicketObj => $args{'TicketObj'} );
490         unless ( $stage ) {
491             $RT::Logger->error(
492                 "Scrip #". $self->id ." is not applied to"
493                 ." queue #". $args{'TicketObj'}->Queue
494             );
495             return (undef);
496         }
497         elsif ( $stage eq 'TransactionCreate') {
498             # Only look at our current Transaction
499             @Transactions = ( $args{'TransactionObj'} );
500         }
501         elsif ( $stage eq 'TransactionBatch') {
502             # Look at all Transactions in this Batch
503             @Transactions = @{ $args{'TicketObj'}->TransactionBatch || [] };
504         }
505         else {
506             $RT::Logger->error( "Unknown Scrip stage: '$stage'" );
507             return (undef);
508         }
509         my $ConditionObj = $self->ConditionObj;
510         foreach my $TransactionObj ( @Transactions ) {
511             # in TxnBatch stage we can select scrips that are not applicable to all txns
512             my $txn_type = $TransactionObj->Type;
513             next unless( $ConditionObj->ApplicableTransTypes =~ /(?:^|,)(?:Any|\Q$txn_type\E)(?:,|$)/i );
514             # Load the scrip's Condition object
515             $ConditionObj->LoadCondition(
516                 ScripObj       => $self,
517                 TicketObj      => $args{'TicketObj'},
518                 TransactionObj => $TransactionObj,
519             );
520
521             if ( $ConditionObj->IsApplicable() ) {
522                 # We found an application Transaction -- return it
523                 $return = $TransactionObj;
524                 last;
525             }
526         }
527     };
528
529     if ($@) {
530         $RT::Logger->error( "Scrip IsApplicable " . $self->Id . " died. - " . $@ );
531         return (undef);
532     }
533
534             return ($return);
535
536 }
537
538
539
540 =head2 Prepare
541
542 Calls the action object's prepare method
543
544 =cut
545
546 sub Prepare {
547     my $self = shift;
548     my %args = ( TicketObj      => undef,
549                  TransactionObj => undef,
550                  @_ );
551
552     my $return;
553     eval {
554         $self->ActionObj->LoadAction(
555             ScripObj       => $self,
556             TicketObj      => $args{'TicketObj'},
557             TransactionObj => $args{'TransactionObj'},
558             TemplateObj    => $self->TemplateObj( $args{'TicketObj'}->Queue ),
559         );
560
561         $return = $self->ActionObj->Prepare();
562     };
563     if ($@) {
564         $RT::Logger->error( "Scrip Prepare " . $self->Id . " died. - " . $@ );
565         return (undef);
566     }
567         unless ($return) {
568         }
569         return ($return);
570 }
571
572
573
574 =head2 Commit
575
576 Calls the action object's commit method
577
578 =cut
579
580 sub Commit {
581     my $self = shift;
582     my %args = ( TicketObj      => undef,
583                  TransactionObj => undef,
584                  @_ );
585
586     my $return;
587     eval {
588         $return = $self->ActionObj->Commit();
589     };
590
591 #Searchbuilder caching isn't perfectly coherent. got to reload the ticket object, since it
592 # may have changed
593     $args{'TicketObj'}->Load( $args{'TicketObj'}->Id );
594
595     if ($@) {
596         $RT::Logger->error( "Scrip Commit " . $self->Id . " died. - " . $@ );
597         return (undef);
598     }
599
600     # Not destroying or weakening hte Action and Condition here could cause a
601     # leak
602
603     return ($return);
604 }
605
606
607
608
609
610 # does an acl check and then passes off the call
611 sub _Set {
612     my $self = shift;
613     my %args = (
614         Field => undef,
615         Value => undef,
616         @_,
617     );
618
619     unless ( $self->CurrentUserHasRight('ModifyScrips') ) {
620         $RT::Logger->debug( "CurrentUser can't modify Scrips" );
621         return ( 0, $self->loc('Permission Denied') );
622     }
623
624
625     if (exists $args{Value}) {
626         if ($args{Field} eq 'CustomIsApplicableCode' || $args{Field} eq 'CustomPrepareCode' || $args{Field} eq 'CustomCommitCode') {
627             unless ( $self->CurrentUser->HasRight( Object => $RT::System,
628                                                    Right  => 'ExecuteCode' ) ) {
629                 return ( 0, $self->loc('Permission Denied') );
630             }
631         }
632         elsif ($args{Field} eq 'Queue') {
633             if ($args{Value}) {
634                 # moving to another queue
635                 my $queue = RT::Queue->new( $self->CurrentUser );
636                 $queue->Load($args{Value});
637                 unless ($queue->Id and $queue->CurrentUserHasRight('ModifyScrips')) {
638                     return ( 0, $self->loc('Permission Denied') );
639                 }
640             } else {
641                 # moving to global
642                 unless ($self->CurrentUser->HasRight( Object => RT->System, Right => 'ModifyScrips' )) {
643                     return ( 0, $self->loc('Permission Denied') );
644                 }
645             }
646         }
647         elsif ($args{Field} eq 'Template') {
648             my $template = RT::Template->new( $self->CurrentUser );
649             $template->Load($args{Value});
650             unless ($template->Id and $template->CurrentUserCanRead) {
651                 return ( 0, $self->loc('Permission Denied') );
652             }
653         }
654     }
655
656     return $self->SUPER::_Set(@_);
657 }
658
659
660 # does an acl check and then passes off the call
661 sub _Value {
662     my $self = shift;
663
664     unless ( $self->CurrentUserHasRight('ShowScrips') ) {
665         $RT::Logger->debug( "CurrentUser can't see scrip #". $self->__Value('id') );
666         return (undef);
667     }
668
669     return $self->__Value(@_);
670 }
671
672 =head2 ACLEquivalenceObjects
673
674 Having rights on any of the queues the scrip applies to is equivalent to
675 having rights on the scrip.
676
677 =cut
678
679 sub ACLEquivalenceObjects {
680     my $self = shift;
681     return unless $self->id;
682     return @{ $self->AddedTo->ItemsArrayRef };
683 }
684
685
686
687 =head2 CompileCheck
688
689 This routine compile-checks the custom prepare, commit, and is-applicable code
690 to see if they are syntactically valid Perl. We eval them in a codeblock to
691 avoid actually executing the code.
692
693 If one of the fields has a compile error, only the first is reported.
694
695 Returns an (ok, message) pair.
696
697 =cut
698
699 sub CompileCheck {
700     my $self = shift;
701
702     for my $method (qw/CustomPrepareCode CustomCommitCode CustomIsApplicableCode/) {
703         my $code = $self->$method;
704         next if !defined($code);
705
706         do {
707             no strict 'vars';
708             eval "sub { $code \n }";
709         };
710         next if !$@;
711
712         my $error = $@;
713         return (0, $self->loc("Couldn't compile [_1] codeblock '[_2]': [_3]", $method, $code, $error));
714     }
715 }
716
717
718 =head2 SetScripAction
719
720 =cut
721
722 sub SetScripAction {
723     my $self  = shift;
724     my $value = shift;
725
726     return ( 0, $self->loc("Action is mandatory argument") ) unless $value;
727
728     require RT::ScripAction;
729     my $action = RT::ScripAction->new( $self->CurrentUser );
730     $action->Load($value);
731     return ( 0, $self->loc( "Action '[_1]' not found", $value ) )
732       unless $action->Id;
733
734     return $self->_Set( Field => 'ScripAction', Value => $action->Id );
735 }
736
737 =head2 SetScripCondition
738
739 =cut
740
741 sub SetScripCondition {
742     my $self  = shift;
743     my $value = shift;
744
745     return ( 0, $self->loc("Condition is mandatory argument") )
746       unless $value;
747
748     require RT::ScripCondition;
749     my $condition = RT::ScripCondition->new( $self->CurrentUser );
750     $condition->Load($value);
751
752     return ( 0, $self->loc( "Condition '[_1]' not found", $value ) )
753       unless $condition->Id;
754
755     return $self->_Set( Field => 'ScripCondition', Value => $condition->Id );
756 }
757
758 =head2 SetTemplate
759
760 =cut
761
762 sub SetTemplate {
763     my $self  = shift;
764     my $value = shift;
765
766     return ( 0, $self->loc("Template is mandatory argument") ) unless $value;
767
768     require RT::Template;
769     my $template = RT::Template->new( $self->CurrentUser );
770     $template->Load($value);
771     return ( 0, $self->loc( "Template '[_1]' not found", $value ) )
772       unless $template->Id;
773
774     return $self->_Set( Field => 'Template', Value => $template->Name );
775 }
776
777 1;
778
779
780
781
782
783
784 =head2 id
785
786 Returns the current value of id.
787 (In the database, id is stored as int(11).)
788
789
790 =cut
791
792
793 =head2 Description
794
795 Returns the current value of Description.
796 (In the database, Description is stored as varchar(255).)
797
798
799
800 =head2 SetDescription VALUE
801
802
803 Set Description to VALUE.
804 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
805 (In the database, Description will be stored as a varchar(255).)
806
807
808 =cut
809
810
811 =head2 ScripCondition
812
813 Returns the current value of ScripCondition.
814 (In the database, ScripCondition is stored as int(11).)
815
816
817
818 =head2 SetScripCondition VALUE
819
820
821 Set ScripCondition to VALUE.
822 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
823 (In the database, ScripCondition will be stored as a int(11).)
824
825
826 =cut
827
828
829 =head2 ScripConditionObj
830
831 Returns the ScripCondition Object which has the id returned by ScripCondition
832
833
834 =cut
835
836 sub ScripConditionObj {
837         my $self = shift;
838         my $ScripCondition =  RT::ScripCondition->new($self->CurrentUser);
839         $ScripCondition->Load($self->__Value('ScripCondition'));
840         return($ScripCondition);
841 }
842
843 =head2 ScripAction
844
845 Returns the current value of ScripAction.
846 (In the database, ScripAction is stored as int(11).)
847
848
849
850 =head2 SetScripAction VALUE
851
852
853 Set ScripAction to VALUE.
854 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
855 (In the database, ScripAction will be stored as a int(11).)
856
857
858 =cut
859
860
861 =head2 ScripActionObj
862
863 Returns the ScripAction Object which has the id returned by ScripAction
864
865
866 =cut
867
868 sub ScripActionObj {
869         my $self = shift;
870         my $ScripAction =  RT::ScripAction->new($self->CurrentUser);
871         $ScripAction->Load($self->__Value('ScripAction'));
872         return($ScripAction);
873 }
874
875 =head2 CustomIsApplicableCode
876
877 Returns the current value of CustomIsApplicableCode.
878 (In the database, CustomIsApplicableCode is stored as text.)
879
880
881
882 =head2 SetCustomIsApplicableCode VALUE
883
884
885 Set CustomIsApplicableCode to VALUE.
886 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
887 (In the database, CustomIsApplicableCode will be stored as a text.)
888
889
890 =cut
891
892
893 =head2 CustomPrepareCode
894
895 Returns the current value of CustomPrepareCode.
896 (In the database, CustomPrepareCode is stored as text.)
897
898
899
900 =head2 SetCustomPrepareCode VALUE
901
902
903 Set CustomPrepareCode to VALUE.
904 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
905 (In the database, CustomPrepareCode will be stored as a text.)
906
907
908 =cut
909
910
911 =head2 CustomCommitCode
912
913 Returns the current value of CustomCommitCode.
914 (In the database, CustomCommitCode is stored as text.)
915
916
917
918 =head2 SetCustomCommitCode VALUE
919
920
921 Set CustomCommitCode to VALUE.
922 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
923 (In the database, CustomCommitCode will be stored as a text.)
924
925
926 =cut
927
928
929 =head2 Disabled
930
931 Returns the current value of Disabled.
932 (In the database, Disabled is stored as smallint(6).)
933
934
935
936 =head2 SetDisabled VALUE
937
938
939 Set Disabled to VALUE.
940 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
941 (In the database, Disabled will be stored as a smallint(6).)
942
943
944 =cut
945
946
947 =head2 Template
948
949 Returns the current value of Template.
950 (In the database, Template is stored as varchar(200).)
951
952
953
954 =head2 SetTemplate VALUE
955
956
957 Set Template to VALUE.
958 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
959 (In the database, Template will be stored as a varchar(200).)
960
961
962 =cut
963
964
965 =head2 Creator
966
967 Returns the current value of Creator.
968 (In the database, Creator is stored as int(11).)
969
970
971 =cut
972
973
974 =head2 Created
975
976 Returns the current value of Created.
977 (In the database, Created is stored as datetime.)
978
979
980 =cut
981
982
983 =head2 LastUpdatedBy
984
985 Returns the current value of LastUpdatedBy.
986 (In the database, LastUpdatedBy is stored as int(11).)
987
988
989 =cut
990
991
992 =head2 LastUpdated
993
994 Returns the current value of LastUpdated.
995 (In the database, LastUpdated is stored as datetime.)
996
997
998 =cut
999
1000
1001
1002 sub _CoreAccessible {
1003     {
1004
1005         id =>
1006                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
1007         Description =>
1008                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
1009         ScripCondition =>
1010                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
1011         ScripAction =>
1012                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
1013         CustomIsApplicableCode =>
1014                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
1015         CustomPrepareCode =>
1016                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
1017         CustomCommitCode =>
1018                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
1019         Disabled =>
1020                 {read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
1021         Template =>
1022                 {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => 'Blank'},
1023         Creator =>
1024                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
1025         Created =>
1026                 {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
1027         LastUpdatedBy =>
1028                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
1029         LastUpdated =>
1030                 {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
1031
1032  }
1033 };
1034
1035 sub FindDependencies {
1036     my $self = shift;
1037     my ($walker, $deps) = @_;
1038
1039     $self->SUPER::FindDependencies($walker, $deps);
1040
1041     $deps->Add( out => $self->ScripConditionObj );
1042     $deps->Add( out => $self->ScripActionObj );
1043     $deps->Add( out => $self->QueueObj ) if $self->QueueObj->Id;
1044     $deps->Add( out => $self->TemplateObj );
1045 }
1046
1047 sub PreInflate {
1048     my $class = shift;
1049     my ($importer, $uid, $data) = @_;
1050
1051     $class->SUPER::PreInflate( $importer, $uid, $data );
1052
1053     if ($data->{Queue} == 0) {
1054         my $obj = RT::Scrip->new( RT->SystemUser );
1055         $obj->LoadByCols( Queue => 0, Description => $data->{Description} );
1056         if ($obj->Id) {
1057             $importer->Resolve( $uid => ref($obj) => $obj->Id );
1058             return;
1059         }
1060     }
1061
1062     return 1;
1063 }
1064
1065 RT::Base->_ImportOverlays();
1066
1067 1;