diff options
author | ivan <ivan> | 2003-07-15 13:16:32 +0000 |
---|---|---|
committer | ivan <ivan> | 2003-07-15 13:16:32 +0000 |
commit | 0ebeec96313dd7edfca340f01f8fbbbac1f4aa1d (patch) | |
tree | 64e852c61cbf09007d52cd6978bfddea721d00d2 /rt/lib/RT/Action | |
parent | c0567c688084e89fcd11bf82348b6c418f1254ac (diff) | |
parent | 945721f48f74d5cfffef7c7cf3a3d6bc2521f5dd (diff) |
This commit was generated by cvs2svn to compensate for changes in r2526,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'rt/lib/RT/Action')
-rw-r--r-- | rt/lib/RT/Action/AutoOpen.pm | 86 | ||||
-rw-r--r-- | rt/lib/RT/Action/CreateTickets.pm | 564 | ||||
-rw-r--r-- | rt/lib/RT/Action/EscalatePriority.pm | 142 | ||||
-rw-r--r-- | rt/lib/RT/Action/SetPriority.pm | 61 | ||||
-rw-r--r-- | rt/lib/RT/Action/UserDefined.pm | 71 |
5 files changed, 924 insertions, 0 deletions
diff --git a/rt/lib/RT/Action/AutoOpen.pm b/rt/lib/RT/Action/AutoOpen.pm new file mode 100644 index 000000000..ea6da1952 --- /dev/null +++ b/rt/lib/RT/Action/AutoOpen.pm @@ -0,0 +1,86 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# 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. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +# This Action will open the BASE if a dependent is resolved. + +package RT::Action::AutoOpen; +require RT::Action::Generic; + +use strict; +use vars qw/@ISA/; +@ISA=qw(RT::Action::Generic); + +#Do what we need to do and send it out. + +#What does this type of Action does + +# {{{ sub Describe +sub Describe { + my $self = shift; + return (ref $self ); +} +# }}} + + +# {{{ sub Prepare +sub Prepare { + my $self = shift; + + # if the ticket is already open or the ticket is new and the message is more mail from the + # requestor, don't reopen it. + + if ( ( $self->TicketObj->Status eq 'open' ) + || ( ( $self->TicketObj->Status eq 'new' ) + && $self->TransactionObj->IsInbound ) + ) { + + return undef; + } + else { + return (1); + } +} +# }}} + +sub Commit { + my $self = shift; + my $oldstatus = $self->TicketObj->Status(); + $self->TicketObj->__Set( Field => 'Status', Value => 'open' ); + $self->TicketObj->_NewTransaction( + Type => 'Set', + Field => 'Status', + OldValue => $oldstatus, + NewValue => 'open', + Data => 'Ticket auto-opened on incoming correspondence' + ); + + + return(1); +} + +eval "require RT::Action::AutoOpen_Vendor"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/AutoOpen_Vendor.pm}); +eval "require RT::Action::AutoOpen_Local"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/AutoOpen_Local.pm}); + +1; diff --git a/rt/lib/RT/Action/CreateTickets.pm b/rt/lib/RT/Action/CreateTickets.pm new file mode 100644 index 000000000..0ab206771 --- /dev/null +++ b/rt/lib/RT/Action/CreateTickets.pm @@ -0,0 +1,564 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# 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. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +package RT::Action::CreateTickets; +require RT::Action::Generic; + +use strict; +use vars qw/@ISA/; +@ISA = qw(RT::Action::Generic); + +use MIME::Entity; + +=head1 NAME + + RT::Action::CreateTickets + +Create one or more tickets according to an externally supplied template. + + +=head1 SYNOPSIS + + ===Create-Ticket: codereview + Subject: Code review for {$Tickets{'TOP'}->Subject} + Depended-On-By: {$Tickets{'TOP'}->Id} + Content: Someone has created a ticket. you should review and approve it, + so they can finish their work + ENDOFCONTENT + +=head1 DESCRIPTION + + +Using the "CreateTickets" ScripAction and mandatory dependencies, RT now has +the ability to model complex workflow. When a ticket is created in a queue +that has a "CreateTickets" scripaction, that ScripAction parses its "Template" + + + +=head2 FORMAT + +CreateTickets uses the template as a template for an ordered set of tickets +to create. The basic format is as follows: + + + ===Create-Ticket: identifier + Param: Value + Param2: Value + Param3: Value + Content: Blah + blah + blah + ENDOFCONTENT + ===Create-Ticket: id2 + Param: Value + Content: Blah + ENDOFCONTENT + + +Each ===Create-Ticket: section is evaluated as its own +Text::Template object, which means that you can embed snippets +of perl inside the Text::Template using {} delimiters, but that +such sections absolutely can not span a ===Create-Ticket boundary. + +After each ticket is created, it's stuffed into a hash called %Tickets +so as to be available during the creation of other tickets during the same +ScripAction. The hash is prepopulated with the ticket which triggered the +ScripAction as $Tickets{'TOP'}; you can also access that ticket using the +shorthand $TOP. + +A simple example: + + ===Create-Ticket: codereview + Subject: Code review for {$Tickets{'TOP'}->Subject} + Depended-On-By: {$Tickets{'TOP'}->Id} + Content: Someone has created a ticket. you should review and approve it, + so they can finish their work + ENDOFCONTENT + + + +A convoluted example + + ===Create-Ticket: approval + { # Find out who the administrators of the group called "HR" + # of which the creator of this ticket is a member + my $name = "HR"; + + my $groups = RT::Groups->new($RT::SystemUser); + $groups->LimitToUserDefinedGroups(); + $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name"); + $groups->WithMember($TransactionObj->CreatorObj->Id); + + my $groupid = $groups->First->Id; + + my $adminccs = RT::Users->new($RT::SystemUser); + $adminccs->WhoHaveRight( + Right => "AdminGroup", + Object =>$groups->First, + IncludeSystemRights => undef, + IncludeSuperusers => 0, + IncludeSubgroupMembers => 0, + ); + + my @admins; + while (my $admin = $adminccs->Next) { + push (@admins, $admin->EmailAddress); + } + } + Queue: Approvals + Type: Approval + AdminCc: {join ("\nAdminCc: ",@admins) } + Depended-On-By: {$Tickets{"TOP"}->Id} + Refers-To: {$Tickets{"TOP"}->Id} + Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject} + Due: {time + 86400} + Content-Type: text/plain + Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject} + Blah + Blah + ENDOFCONTENT + ===Create-Ticket: two + Subject: Manager approval + Depended-On-By: {$Tickets{"TOP"}->Id} + Refers-On: {$Tickets{"approval"}->Id} + Queue: Approvals + Content-Type: text/plain + Content: + Your approval is requred for this ticket, too. + ENDOFCONTENT + +=head2 Acceptable fields + +A complete list of acceptable fields for this beastie: + + + * Queue => Name or id# of a queue + Subject => A text string + ! Status => A valid status. defaults to 'new' + Due => Dates can be specified in seconds since the epoch + to be handled literally or in a semi-free textual + format which RT will attempt to parse. + + + + Starts => + Started => + Resolved => + Owner => Username or id of an RT user who can and should own + this ticket + + Requestor => Email address + + Cc => Email address + + AdminCc => Email address + TimeWorked => + TimeEstimated => + TimeLeft => + InitialPriority => + FinalPriority => + Type => + +! DependsOn => + +! DependedOnBy => + +! RefersTo => + +! ReferredToBy => + +! Members => + +! MemberOf => + Content => content. Can extend to multiple lines. Everything + within a template after a Content: header is treated + as content until we hit a line containing only + ENDOFCONTENT + ContentType => the content-type of the Content field + CustomField-<id#> => custom field value + +Fields marked with an * are required. + +Fields marked with a + man have multiple values, simply +by repeating the fieldname on a new line with an additional value. + +Fields marked with a ! are postponed to be processed after all +tickets in the same actions are created. Except for 'Status', those +field can also take a ticket name within the same action (i.e. +the identifiers after ==Create-Ticket), instead of raw Ticket ID +numbers. + +When parsed, field names are converted to lowercase and have -s stripped. +Refers-To, RefersTo, refersto, refers-to and r-e-f-er-s-tO will all +be treated as the same thing. + + +=begin testing + +ok (require RT::Action::CreateTickets); +use_ok(RT::Scrip); +use_ok(RT::Template); +use_ok(RT::ScripAction); +use_ok(RT::ScripCondition); +use_ok(RT::Ticket); + +my $approvalsq = RT::Queue->new($RT::SystemUser); +$approvalsq->Create(Name => 'Approvals'); +ok ($approvalsq->Id, "Created Approvals test queue"); + + +my $approvals = +'===Create-Ticket: approval +{ my $name = "HR"; + my $groups = RT::Groups->new($RT::SystemUser); + $groups->LimitToUserDefinedGroups(); + $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name"); + $groups->WithMember($Transaction->CreatorObj->Id); + + my $groupid = $groups->First->Id; + + my $adminccs = RT::Users->new($RT::SystemUser); + $adminccs->WhoHaveRight(Right => "AdminGroup", IncludeSystemRights => undef, IncludeSuperusers => 0, IncludeSubgroupMembers => 0, Object => $groups->First); + + my @admins; + while (my $admin = $adminccs->Next) { + push (@admins, $admin->EmailAddress); + } +} +Queue: Approvals +Type: Approval +AdminCc: {join ("\nAdminCc: ",@admins) } +Depended-On-By: {$Tickets{"TOP"}->Id} +Refers-To: {$Tickets{"TOP"}->Id} +Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject} +Due: {time + 86400} +Content-Type: text/plain +Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject} +Blah +Blah +ENDOFCONTENT +===Create-Ticket: two +Subject: Manager approval. +Depends-On: {$Tickets{"approval"}->Id} +Queue: Approvals +Content-Type: text/plain +Content: +Your minion approved this ticket. you ok with that? +ENDOFCONTENT +'; + +ok ($approvals =~ /Content/, "Read in the approvals template"); + +my $apptemp = RT::Template->new($RT::SystemUser); +$apptemp->Create( Content => $approvals, Name => "Approvals", Queue => "0"); + +ok ($apptemp->Id); + +my $q = RT::Queue->new($RT::SystemUser); +$q->Create(Name => 'WorkflowTest'); +ok ($q->Id, "Created workflow test queue"); + +my $scrip = RT::Scrip->new($RT::SystemUser); +my ($sval, $smsg) =$scrip->Create( ScripCondition => 'On Transaction', + ScripAction => 'Create Tickets', + Template => 'Approvals', + Queue => $q->Id); +ok ($sval, $smsg); +ok ($scrip->Id, "Created the scrip"); +ok ($scrip->TemplateObj->Id, "Created the scrip template"); +ok ($scrip->ConditionObj->Id, "Created the scrip condition"); +ok ($scrip->ActionObj->Id, "Created the scrip action"); + +my $t = RT::Ticket->new($RT::SystemUser); +$t->Create(Subject => "Sample workflow test", + Owner => "root", + Queue => $q->Id); + + +=end testing + + +=head1 AUTHOR + +Jesse Vincent <jesse@bestpractical.com> + +=head1 SEE ALSO + +perl(1). + +=cut + +my %LINKTYPEMAP = ( + MemberOf => { Type => 'MemberOf', + Mode => 'Target', }, + Members => { Type => 'MemberOf', + Mode => 'Base', }, + HasMember => { Type => 'MemberOf', + Mode => 'Base', }, + RefersTo => { Type => 'RefersTo', + Mode => 'Target', }, + ReferredToBy => { Type => 'RefersTo', + Mode => 'Base', }, + DependsOn => { Type => 'DependsOn', + Mode => 'Target', }, + DependedOnBy => { Type => 'DependsOn', + Mode => 'Base', }, + +); + +# {{{ Scrip methods (Commit, Prepare) + +# {{{ sub Commit +#Do what we need to do and send it out. +sub Commit { + my $self = shift; + my (@links, @postponed); + + # XXX: cargo cult programming that works. i'll be back. + use bytes; + + # Create all the tickets we care about + return(1) unless $self->TicketObj->Type eq 'ticket'; + + %T::Tickets = (); + + foreach my $template_id ( @{ $self->{'template_order'} } ) { + $T::Tickets{'TOP'} = $T::TOP = $self->TicketObj; + $RT::Logger->debug("Workflow: processing $template_id of $T::TOP"); + + $T::ID = $template_id; + @T::AllID = @{ $self->{'template_order'} }; + + my $template = Text::Template->new( + TYPE => 'STRING', + SOURCE => $self->{'templates'}->{$template_id} + ); + + $RT::Logger->debug("Workflow: evaluating\n$self->{templates}{$template_id}"); + + my $err; + my $filled_in = $template->fill_in( PACKAGE => 'T', BROKEN => sub { + $err = { @_ }->{error}; + } ); + + $RT::Logger->debug("Workflow: yielding\n$filled_in"); + + if ($err) { + $RT::Logger->error("Ticket creation failed for ".$self->TicketObj->Id." ".$err); + while (my ($k, $v) = each %T::X) { + $RT::Logger->debug("Eliminating $template_id from ${k}'s parents."); + delete $v->{$template_id}; + } + next; + } + + my %args; + my @lines = ( split ( /\n/, $filled_in ) ); + while ( defined(my $line = shift @lines) ) { + if ( $line =~ /^(.*?):(?:\s+(.*))?$/ ) { + my $value = $2; + my $tag = lc ($1); + $tag =~ s/-//g; + + if (ref($args{$tag})) { #If it's an array, we want to push the value + push @{$args{$tag}}, $value; + } + elsif (defined ($args{$tag})) { #if we're about to get a second value, make it an array + $args{$tag} = [$args{$tag}, $value]; + } + else { #if there's nothing there, just set the value + $args{ $tag } = $value; + } + + if ( $tag eq 'content' ) { #just build up the content + # convert it to an array + $args{$tag} = defined($value) ? [ $value."\n" ] : []; + while ( defined(my $l = shift @lines) ) { + last if ($l =~ /^ENDOFCONTENT\s*$/) ; + push @{$args{'content'}}, $l."\n"; + } + } + } + } + + foreach my $date qw(due starts started resolved) { + my $dateobj = RT::Date->new($RT::SystemUser); + next unless $args{$date}; + if ($args{$date} =~ /^\d+$/) { + $dateobj->Set(Format => 'unix', Value => $args{$date}); + } else { + $dateobj->Set(Format => 'unknown', Value => $args{$date}); + } + $args{$date} = $dateobj->ISO; + } + my $mimeobj = MIME::Entity->new(); + $mimeobj->build(Type => $args{'contenttype'}, + Data => $args{'content'}); + # Now we have a %args to work with. + # Make sure we have at least the minimum set of + # reasonable data and do our thang + $T::Tickets{$template_id} ||= RT::Ticket->new($RT::SystemUser); + + # Deferred processing + push @links, ( + $T::Tickets{$template_id}, { + DependsOn => $args{'dependson'}, + DependedOnBy => $args{'dependedonby'}, + RefersTo => $args{'refersto'}, + ReferredToBy => $args{'referredtoby'}, + Members => $args{'members'}, + MemberOf => $args{'memberof'}, + } + ); + + push @postponed, ( + # Status is postponed so we don't violate dependencies + $T::Tickets{$template_id}, { + Status => $args{'status'}, + } + ); + + $args{'requestor'} ||= $self->TicketObj->Requestors->MemberEmailAddresses; + + my %ticketargs = ( Queue => $args{'queue'}, + Subject=> $args{'subject'}, + Status => 'new', + Due => $args{'due'}, + Starts => $args{'starts'}, + Started => $args{'started'}, + Resolved => $args{'resolved'}, + Owner => $args{'owner'}, + Requestor => $args{'requestor'}, + Cc => $args{'cc'}, + AdminCc=> $args{'admincc'}, + TimeWorked =>$args{'timeworked'}, + TimeEstimated =>$args{'timeestimated'}, + TimeLeft =>$args{'timeleft'}, + InitialPriority => $args{'initialpriority'}, + FinalPriority => $args{'finalpriority'}, + Type => $args{'type'}, + MIMEObj => $mimeobj); + + + foreach my $key (keys(%args)) { + $key =~ /^customfield-(\d+)$/ or next; + $ticketargs{ "CustomField-" . $1 } = $args{$key}; + } + + my ($id, $transid, $msg) = $T::Tickets{$template_id}->Create(%ticketargs); + if (!$id) { + $RT::Logger->error( + "Couldn't create related ticket $template_id for ". + $self->TicketObj->Id." ".$msg + ); + next; + } + + $RT::Logger->debug("Assigned $template_id with $id"); + $T::Tickets{$template_id}->SetOriginObj($self->TicketObj) + if $T::Tickets{$template_id}->can('SetOriginObj'); + } + + # postprocessing: add links + + while (my $ticket = shift(@links)) { + $RT::Logger->debug("Handling links for " . $ticket->Id); + my %args = %{shift(@links)}; + + foreach my $type ( keys %LINKTYPEMAP ) { + next unless (defined $args{$type}); + foreach my $link ( + ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) ) + { + if (!exists $T::Tickets{$link}) { + $RT::Logger->debug("Skipping $type link for $link (non-existent)"); + next; + } + $RT::Logger->debug("Building $type link for $link: " . $T::Tickets{$link}->Id); + $link = $T::Tickets{$link}->Id; + + my ( $wval, $wmsg ) = $ticket->AddLink( + Type => $LINKTYPEMAP{$type}->{'Type'}, + $LINKTYPEMAP{$type}->{'Mode'} => $link, + Silent => 1 + ); + + $RT::Logger->warning("AddLink thru $link failed: $wmsg") unless $wval; + # push @non_fatal_errors, $wmsg unless ($wval); + } + + } + } + + # postponed actions -- Status only, currently + while (my $ticket = shift(@postponed)) { + $RT::Logger->debug("Handling postponed actions for $ticket"); + my %args = %{shift(@postponed)}; + + $ticket->SetStatus($args{Status}) if defined $args{Status}; + } + + return(1); +} +# }}} + +# {{{ sub Prepare + +sub Prepare { + my $self = shift; + + unless ($self->TemplateObj) { + $RT::Logger->warning("No template object handed to $self\n"); + } + + unless ($self->TransactionObj) { + $RT::Logger->warning("No transaction object handed to $self\n"); + + } + + unless ($self->TicketObj) { + $RT::Logger->warning("No ticket object handed to $self\n"); + + } + + + + +my $template_id; +foreach my $line (split(/\n/,$self->TemplateObj->Content)) { + if ($line =~ /^===Create-Ticket: (.*)$/) { + $template_id = $1; + push @{$self->{'template_order'}},$template_id; + } else { + $self->{'templates'}->{$template_id} .= $line."\n"; + } + + +} + + return 1; + +} + +# }}} + +# }}} + +eval "require RT::Action::CreateTickets_Vendor"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/CreateTickets_Vendor.pm}); +eval "require RT::Action::CreateTickets_Local"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/CreateTickets_Local.pm}); + +1; + diff --git a/rt/lib/RT/Action/EscalatePriority.pm b/rt/lib/RT/Action/EscalatePriority.pm new file mode 100644 index 000000000..7ed63ae01 --- /dev/null +++ b/rt/lib/RT/Action/EscalatePriority.pm @@ -0,0 +1,142 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# 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. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +=head1 NAME + + RT::Action::EscalatePriority + +=head1 DESCRIPTION + +EscalatePriority is a ScripAction which is NOT intended to be called per +transaction. It's intended to be called by an RT escalation daemon. +(The daemon is called escalator). + +EsclatePriority uses the following formula to change a ticket's priority: + + Priority = Priority + (( FinalPriority - Priority ) / ( DueDate-Today)) + +Unless the duedate is past, in which case priority gets bumped straight +to final priority. + +In this way, priority is either increased or decreased toward the final priority +as the ticket heads toward its due date. + + +=cut + + +package RT::Action::EscalatePriority; +require RT::Action::Generic; + +use strict; +use vars qw/@ISA/; +@ISA=qw(RT::Action::Generic); + +#Do what we need to do and send it out. + +#What does this type of Action does + +# {{{ sub Describe +sub Describe { + my $self = shift; + return (ref $self . " will move a ticket's priority toward its final priority."); +} +# }}} + + +# {{{ sub Prepare +sub Prepare { + my $self = shift; + + if ($self->TicketObj->Priority() == $self->TicketObj->FinalPriority()) { + # no update necessary. + return 0; + } + + #compute the number of days until the ticket is due + my $due = $self->TicketObj->DueObj(); + + + # If we don't have a due date, adjust the priority by one + # until we hit the final priority + if ($due->Unix() < 1) { + if ( $self->TicketObj->Priority > $self->TicketObj->FinalPriority ){ + $self->{'prio'} = ($self->TicketObj->Priority - 1); + return 1; + } + elsif ( $self->TicketObj->Priority < $self->TicketObj->FinalPriority ){ + $self->{'prio'} = ($self->TicketObj->Priority + 1); + return 1; + } + # otherwise the priority is at the final priority. we don't need to + # Continue + else { + return 0; + } + } + + # we've got a due date. now there are other things we should do + else { + my $diff_in_seconds = $due->Diff(time()); + my $diff_in_days = int( $diff_in_seconds / 86400); + + #if we haven't hit the due date yet + if ($diff_in_days > 0 ) { + + # compute the difference between the current priority and the + # final priority + + my $prio_delta = + $self->TicketObj->FinalPriority() - $self->TicketObj->Priority; + + my $inc_priority_by = int( $prio_delta / $diff_in_days ); + + #set the ticket's priority to that amount + $self->{'prio'} = $self->TicketObj->Priority + $inc_priority_by; + + } + #if $days is less than 1, set priority to final_priority + else { + $self->{'prio'} = $self->TicketObj->FinalPriority(); + } + + } + return 1; +} +# }}} + +sub Commit { + my $self = shift; + my ($val, $msg) = $self->TicketObj->SetPriority($self->{'prio'}); + + unless ($val) { + $RT::Logger->debug($self . " $msg\n"); + } +} + +eval "require RT::Action::EscalatePriority_Vendor"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/EscalatePriority_Vendor.pm}); +eval "require RT::Action::EscalatePriority_Local"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/EscalatePriority_Local.pm}); + +1; diff --git a/rt/lib/RT/Action/SetPriority.pm b/rt/lib/RT/Action/SetPriority.pm new file mode 100644 index 000000000..515eeb58c --- /dev/null +++ b/rt/lib/RT/Action/SetPriority.pm @@ -0,0 +1,61 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# 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. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +package RT::Action::SetPriority; +require RT::Action::Generic; + +use strict; +use vars qw/@ISA/; +@ISA=qw(RT::Action::Generic); + +#Do what we need to do and send it out. + +#What does this type of Action does + +# {{{ sub Describe +sub Describe { + my $self = shift; + return (ref $self . " will set a ticket's priority to the argument provided."); +} +# }}} + + +# {{{ sub Prepare +sub Prepare { + # nothing to prepare + return 1; +} +# }}} + +sub Commit { + my $self = shift; + $self->TicketObj->SetPriority($self->Argument); + +} + +eval "require RT::Action::SetPriority_Vendor"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SetPriority_Vendor.pm}); +eval "require RT::Action::SetPriority_Local"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SetPriority_Local.pm}); + +1; diff --git a/rt/lib/RT/Action/UserDefined.pm b/rt/lib/RT/Action/UserDefined.pm new file mode 100644 index 000000000..e2e3d72ce --- /dev/null +++ b/rt/lib/RT/Action/UserDefined.pm @@ -0,0 +1,71 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# +# (Except where explictly superceded by other copyright notices) +# +# 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. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK + + +package RT::Action::UserDefined; +use RT::Action::Generic; + +use strict; +use vars qw/@ISA/; +@ISA = qw(RT::Action::Generic); + +=head2 Prepare + +This happens on every transaction. it's always applicable + +=cut + +sub Prepare { + my $self = shift; + my $retval = eval $self->ScripObj->CustomPrepareCode; + if ($@) { + $RT::Logger->error("Scrip ".$self->ScripObj->Id. " Prepare failed: ".$@); + return (undef); + } + return ($retval); +} + +=head2 Commit + +This happens on every transaction. it's always applicable + +=cut + +sub Commit { + my $self = shift; + my $retval = eval $self->ScripObj->CustomCommitCode; + if ($@) { + $RT::Logger->error("Scrip ".$self->ScripObj->Id. " Commit failed: ".$@); + return (undef); + } + return ($retval); +} + +eval "require RT::Action::UserDefined_Vendor"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/UserDefined_Vendor.pm}); +eval "require RT::Action::UserDefined_Local"; +die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/UserDefined_Local.pm}); + +1; + |