diff options
Diffstat (limited to 'rt/lib/RT/Interface')
| -rw-r--r-- | rt/lib/RT/Interface/Web.pm | 39 | ||||
| -rw-r--r-- | rt/lib/RT/Interface/Web_Vendor.pm | 302 |
2 files changed, 333 insertions, 8 deletions
diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm index f56abb362..959c80334 100644 --- a/rt/lib/RT/Interface/Web.pm +++ b/rt/lib/RT/Interface/Web.pm @@ -438,7 +438,11 @@ sub MaybeRejectPrivateComponentRequest { autohandler | # requesting this directly is suspicious l ) # loc component ( $ | / ) # trailing slash or end of path - }xi) { + }xi + && $path !~ m{ /RTx/Statistics/\w+/Elements/Chart }xi + ) + { + warn "rejecting private component $path\n"; $m->abort(403); } @@ -1379,13 +1383,22 @@ sub ProcessUpdateMessage { my $bcc = $args{ARGSRef}->{'UpdateBcc'}; my $cc = $args{ARGSRef}->{'UpdateCc'}; + my %txn_customfields; + + foreach my $key ( keys %{ $args{ARGSRef} } ) { + if ( $key =~ /^(?:Object-RT::Transaction--)?CustomField-(\d+)/ ) { + $txn_customfields{$key} = $args{ARGSRef}->{$key}; + } + } + my %message_args = ( CcMessageTo => $cc, BccMessageTo => $bcc, Sign => $args{ARGSRef}->{'Sign'}, Encrypt => $args{ARGSRef}->{'Encrypt'}, MIMEObj => $Message, - TimeTaken => $args{ARGSRef}->{'UpdateTimeWorked'} + TimeTaken => $args{ARGSRef}->{'UpdateTimeWorked'}, + CustomFields => \%txn_customfields, ); my @temp_squelch; @@ -1421,14 +1434,17 @@ sub ProcessUpdateMessage { } my @results; + # Do the update via the appropriate Ticket method if ( $args{ARGSRef}->{'UpdateType'} =~ /^(private|public)$/ ) { - my ( $Transaction, $Description, $Object ) = $args{TicketObj}->Comment(%message_args); + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Comment(%message_args); push( @results, $Description ); - $Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; + #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; } elsif ( $args{ARGSRef}->{'UpdateType'} eq 'response' ) { - my ( $Transaction, $Description, $Object ) = $args{TicketObj}->Correspond(%message_args); + my ( $Transaction, $Description, $Object ) = + $args{TicketObj}->Correspond(%message_args); push( @results, $Description ); - $Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; + #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object; } else { push( @results, loc("Update type was neither correspondence nor comment.") . " " . loc("Update not recorded.") ); @@ -1547,8 +1563,6 @@ sub ParseDateToISO { sub ProcessACLChanges { my $ARGSref = shift; - #XXX: why don't we get ARGSref like in other Process* subs? - my @results; foreach my $arg ( keys %$ARGSref ) { @@ -1763,6 +1777,8 @@ sub ProcessTicketCustomFieldUpdates { $ARGSRef->{"Object-RT::Ticket-$1"} = delete $ARGSRef->{$arg}; } elsif ( $arg =~ /^CustomField-(\d+-.*)/ ) { $ARGSRef->{"Object-RT::Ticket--$1"} = delete $ARGSRef->{$arg}; + } elsif ( $arg =~ /^Object-RT::Transaction-(\d*)-CustomField/ ) { + delete $ARGSRef->{$arg}; # don't try to update transaction fields } } @@ -1838,6 +1854,9 @@ sub _ProcessObjectCustomFieldUpdates { # skip category argument next if $arg eq 'Category'; + # and TimeUnits + next if $arg eq 'Value-TimeUnits'; + # since http won't pass in a form element with a null value, we need # to fake it if ( $arg eq 'Values-Magic' ) { @@ -1916,6 +1935,9 @@ sub _ProcessObjectCustomFieldUpdates { $values_hash{$val} = 1 if $val; } + # For Date Cfs, @values is empty when there is no changes (no datas in form input) + return @results if ( $cf->Type eq 'Date' && ! @values ); + $cf_values->RedoSearch; while ( my $cf_value = $cf_values->Next ) { next if $values_hash{ $cf_value->id }; @@ -2299,6 +2321,7 @@ sub _parse_saved_search { return ( _load_container_object( $obj_type, $obj_id ), $search_id ); } +package RT::Interface::Web; RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Web_Vendor.pm b/rt/lib/RT/Interface/Web_Vendor.pm new file mode 100644 index 000000000..c79222be5 --- /dev/null +++ b/rt/lib/RT/Interface/Web_Vendor.pm @@ -0,0 +1,302 @@ +# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am> +# Copyright (c) 2008 Freeside Internet Services, Inc. +# +# 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. + +=head1 NAME + +RT::Interface::Web_Vendor + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +Freeside vendor overlay for RT::Interface::Web. + +=begin testing + +use_ok(RT::Interface::Web_Vendor); + +=end testing + +=cut + +#package RT::Interface::Web; +#use strict; + +package HTML::Mason::Commands; +use strict; +no warnings qw(redefine); + +=head2 ProcessTicketCustomers + +=cut + +sub ProcessTicketCustomers { + my %args = ( + TicketObj => undef, + ARGSRef => undef, + Debug => 0, + @_ + ); + my @results = (); + + my $Ticket = $args{'TicketObj'}; + my $ARGSRef = $args{'ARGSRef'}; + my $Debug = $args{'Debug'}; + my $me = 'ProcessTicketCustomers'; + + ### false laziness w/RT::Interface::Web::ProcessTicketLinks + # Delete links that are gone gone gone. + foreach my $arg ( keys %$ARGSRef ) { + if ( $arg =~ /DeleteLink-(.*?)-(DependsOn|MemberOf|RefersTo)-(.*)$/ ) { + my $base = $1; + my $type = $2; + my $target = $3; + + push @results, + "Trying to delete: Base: $base Target: $target Type $type"; + my ( $val, $msg ) = $Ticket->DeleteLink( Base => $base, + Type => $type, + Target => $target ); + + push @results, $msg; + + } + + } + ### + + ### + #find new customers + ### + + my @custnums = map { /^Ticket-AddCustomer-(\d+)$/; $1 } + grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} } + keys %$ARGSRef; + + #my @delete_custnums = + # map { /^Ticket-AddCustomer-(\d+)$/; $1 } + # grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} } + # keys %$ARGSRef; + + ### + #figure out if we're going to auto-link requestors, and find them if so + ### + + my $num_cur_cust = $Ticket->Customers->Count; + my $num_new_cust = scalar(@custnums); + warn "$me: $num_cur_cust current customers / $num_new_cust new customers\n" + if $Debug; + + #if we're linking the first ticket to one customer + my $link_requestors = ( $num_cur_cust == 0 && $num_new_cust == 1 ); + warn "$me: adding a single customer to a previously customerless". + " ticket, so linking customers to requestor too\n" + if $Debug && $link_requestors; + + my @Requestors = (); + if ( $link_requestors ) { + + #find any requestors without customers + @Requestors = + grep { ! $_->Customers->Count } + @{ $Ticket->Requestors->UserMembersObj->ItemsArrayRef }; + + warn "$me: found ". scalar(@Requestors). " requestors without". + " customers; linking them\n" + if $Debug; + + } + + ### + #link ticket (and requestors) to customers + ### + + foreach my $custnum ( @custnums ) { + + my @link = ( 'Type' => 'MemberOf', + 'Target' => "freeside://freeside/cust_main/$custnum", + ); + + my( $val, $msg ) = $Ticket->AddLink(@link); + push @results, $msg; + + #add customer links to requestors + foreach my $Requestor ( @Requestors ) { + my( $val, $msg ) = $Requestor->AddLink(@link); + push @results, $msg; + warn "$me: linking requestor to custnum $custnum: $msg\n" + if $Debug > 1; + } + + } + + return @results; + +} + +#false laziness w/above... eventually it should go away in favor of this +sub ProcessObjectCustomers { + my %args = ( + Object => undef, + ARGSRef => undef, + @_ + ); + my @results = (); + + my $Object = $args{'Object'}; + my $ARGSRef = $args{'ARGSRef'}; + + ### false laziness w/RT::Interface::Web::ProcessTicketLinks + # Delete links that are gone gone gone. + foreach my $arg ( keys %$ARGSRef ) { + if ( $arg =~ /DeleteLink-(.*?)-(DependsOn|MemberOf|RefersTo)-(.*)$/ ) { + my $base = $1; + my $type = $2; + my $target = $3; + + push @results, + "Trying to delete: Base: $base Target: $target Type $type"; + my ( $val, $msg ) = $Object->DeleteLink( Base => $base, + Type => $type, + Target => $target ); + + push @results, $msg; + + } + + } + ### + + #my @delete_custnums = + # map { /^Object-AddCustomer-(\d+)$/; $1 } + # grep { /^Object-AddCustomer-(\d+)$/ && $ARGSRef->{$_} } + # keys %$ARGSRef; + + my @custnums = map { /^Object-AddCustomer-(\d+)$/; $1 } + grep { /^Object-AddCustomer-(\d+)$/ && $ARGSRef->{$_} } + keys %$ARGSRef; + + foreach my $custnum ( @custnums ) { + my( $val, $msg ) = + $Object->AddLink( 'Type' => 'MemberOf', + 'Target' => "freeside://freeside/cust_main/$custnum", + ); + push @results, $msg; + } + + return @results; + +} + +=head2 ProcessTicketBasics ( TicketObj => $Ticket, ARGSRef => \%ARGS ); + +Updates all core ticket fields except Status, and returns an array of results +messages. + +=cut + +sub ProcessTicketBasics { + + my %args = ( + TicketObj => undef, + ARGSRef => undef, + @_ + ); + + my $TicketObj = $args{'TicketObj'}; + my $ARGSRef = $args{'ARGSRef'}; + + # {{{ Set basic fields + my @attribs = qw( + Subject + FinalPriority + Priority + TimeEstimated + TimeWorked + TimeLeft + Type + Queue + ); + + if ( $ARGSRef->{'Queue'} and ( $ARGSRef->{'Queue'} !~ /^(\d+)$/ ) ) { + my $tempqueue = RT::Queue->new($RT::SystemUser); + $tempqueue->Load( $ARGSRef->{'Queue'} ); + if ( $tempqueue->id ) { + $ARGSRef->{'Queue'} = $tempqueue->id; + } + } + + my @results = UpdateRecordObject( + AttributesRef => \@attribs, + Object => $TicketObj, + ARGSRef => $ARGSRef, + ); + + # We special case owner changing, so we can use ForceOwnerChange + if ( $ARGSRef->{'Owner'} && ( $TicketObj->Owner != $ARGSRef->{'Owner'} ) ) { + my ($ChownType); + if ( $ARGSRef->{'ForceOwnerChange'} ) { + $ChownType = "Force"; + } else { + $ChownType = "Give"; + } + + my ( $val, $msg ) = $TicketObj->SetOwner( $ARGSRef->{'Owner'}, $ChownType ); + push( @results, $msg ); + } + + # }}} + + return (@results); +} + +=head2 ProcessTicketStatus (TicketObj => RT::Ticket, ARGSRef => {}) + +Process updates to the 'Status' field of the ticket. If the new value +of Status is 'resolved', this will check required custom fields before +allowing the update. + +=cut + +sub ProcessTicketStatus { + my %args = ( + TicketObj => undef, + ARGSRef => undef, + @_ + ); + + my $TicketObj = $args{'TicketObj'}; + my $ARGSRef = $args{'ARGSRef'}; + my @results; + + return () if !$ARGSRef->{'Status'}; + + if ( lc( $ARGSRef->{'Status'} ) eq 'resolved' ) { + foreach my $field ( $TicketObj->MissingRequiredFields ) { + push @results, loc('Missing required field: [_1]', $field->Name); + } + } + if ( @results ) { + $m->notes('RedirectToBasics' => 1); + return @results; + } + + return UpdateRecordObject( + AttributesRef => [ 'Status' ], + Object => $TicketObj, + ARGSRef => $ARGSRef, + ); +} + +1; + |
