[Bps-public-commit] RT-Extension-MandatoryOnTransition branch, support-coreroles-and-customroles, created. 0.17-2-g609d0c3

Craig Kaiser craig at bestpractical.com
Fri Jan 4 16:53:38 EST 2019


The branch, support-coreroles-and-customroles has been created
        at  609d0c3d66ddd2615a7e81b23aab21ad37355bcc (commit)

- Log -----------------------------------------------------------------
commit 53b566f92e4b53cf044b24013003c8cb8b0100e8
Author: Craig Kaiser <craig at bestpractical.com>
Date:   Fri Jan 4 11:11:15 2019 -0500

    Support customrole mandatoryontransition conditions
    
    Use the syntax 'CustomRole.MyRole' to set mandatory conditions for
    customrole values. Pass a group key to specify if one of the current
    users for the customrole must be a member of a specific group.
    
    Before

diff --git a/lib/RT/Extension/MandatoryOnTransition.pm b/lib/RT/Extension/MandatoryOnTransition.pm
index d238c18..3786e81 100644
--- a/lib/RT/Extension/MandatoryOnTransition.pm
+++ b/lib/RT/Extension/MandatoryOnTransition.pm
@@ -127,7 +127,7 @@ config option.  This option takes the generic form of:
 
     Set( %MandatoryOnTransition,
         'QueueName' => {
-            'from -> to' => [ 'BasicField', 'CF.MyField', ],
+            'from -> to' => [ 'BasicField', 'CF.MyField', 'CustomRole.MyRole' ],
         },
     );
 
@@ -146,10 +146,11 @@ Category selection before resolving tickets in every other queue.
 
     Set( %MandatoryOnTransition,
         Helpdesk => {
-            '* -> resolved' => ['TimeWorked', 'CF.Resolution'],
+            '* -> resolved' => ['TimeWorked', 'CF.Resolution', 'CustomRole.Analyst'],
         },
         '*' => {
             '* -> resolved' => ['CF.Category'],
+            'CustomRole.Analyst' => {transition => '* -> open', group => 'Engineering'},
         },
     );
 
@@ -340,6 +341,8 @@ sub RequiredFields {
     my @core = grep { !/^CF\./i && $core_supported{$_} } @$required;
     my @cfs  =  map { /^CF\.(.+)$/i; $1; }
                grep { /^CF\./i } @$required;
+    my @roles = map { /^(:?[CustomRole\.]?.+)$/i; $1; }
+               grep { /^CustomRole\.||AdminCc||Cc||Requestor/i } @$required;
 
     # Pull out any must_be or must_not_be rules
     my %cf_must_values = ();
@@ -359,7 +362,25 @@ sub RequiredFields {
             }
         }
     }
-    return (\@core, \@cfs, \%cf_must_values);
+
+    my %role_group_values;
+    foreach my $role (@roles){
+        if ( $config{$role} ){
+            my $transition = $config{$role}->{'transition'};
+            unless ( $transition ){
+                RT->Logger->error("No transition defined in group rules for $role");
+                next;
+            }
+
+            if ( $transition eq "$from -> $to"
+                || $transition eq "* -> $to"
+                || $transition eq "$from -> *" ) {
+
+                $role_group_values{$role} = $config{$role};
+            }
+        }
+    }
+    return (\@core, \@cfs, \@roles, \%cf_must_values, \%role_group_values);
 }
 
 =head3 CheckMandatoryFields
@@ -412,13 +433,15 @@ sub CheckMandatoryFields {
     }
 
     # Some convenience variables set depending on what gets passed
-    my ($CFs, $CurrentUser);
+    my ($CFs, $CRs, $CurrentUser);
     if ( $args{'Ticket'} ){
         $CFs = $args{'Ticket'}->CustomFields;
+        $CRs = $args{'Ticket'}->QueueObj->CustomRoles;
         $CurrentUser = $args{'Ticket'}->CurrentUser();
     }
     elsif ( $args{'Queue'} ){
         $CFs = $args{'Queue'}->TicketCustomFields;
+        $CRs = $args{'Queue'}->CustomRoles;
         $CurrentUser = $args{'Queue'}->CurrentUser();
     }
     else{
@@ -426,7 +449,7 @@ sub CheckMandatoryFields {
         return \@errors;
     }
 
-    my ($core, $cfs, $must_values) = $self->RequiredFields(
+    my ($core, $cfs, $roles, $cf_must_values, $role_group_values) = $self->RequiredFields(
         Ticket  => $args{'Ticket'},
         Queue   => $args{'Queue'} ? $args{'Queue'}->Name : undef,
         From    => $args{'From'},
@@ -434,7 +457,7 @@ sub CheckMandatoryFields {
         NewQueue => $$ARGSRef{'Queue'},
     );
 
-    return \@errors unless @$core or @$cfs;
+    return \@errors unless @$core or @$cfs or @$roles;
 
     my $transition =  ($args{'From'} ||'') ne ($args{'To'} || '') ? 'Status' : 'Queue';
 
@@ -500,6 +523,54 @@ sub CheckMandatoryFields {
             $label, $CurrentUser->loc($transition),  $CurrentUser->loc($field_label{$transition}));
     }
 
+    if ( @$roles ) {
+        foreach my $role (@$roles) {
+            my $role_values;
+            my $role_arg = $role;
+            my $role_full = $role;
+
+            if ( $role =~ 'CustomRole.' ) {
+                if ( not $CRs ){
+                    $RT::Logger->error("Custom Roles object required to process mandatory custom roles");
+                    return \@errors;
+                }
+                $role =~ qr/^CustomRole\.(.+)$/i;
+                $role = $1;
+
+                my $role_object = RT::CustomRole->new($args{Ticket}->CurrentUser);
+
+                my ($ret, $msg) = $role_object->Load($role);
+                push @errors, $CurrentUser->loc("Failed to load customrole $role:  $msg") unless $ret;
+                return \@errors unless $ret;
+
+                $role_arg = 'RT::CustomRole-' . $role_object->Id;
+
+                ($ret, $msg) = $role_values = $args{Ticket}->RoleGroup($role_object->GroupType);
+                push @errors, $CurrentUser->loc("$msg") unless $ret;
+                return \@errors unless $ret;
+            } else {
+                $role_values = RT::Group->new($args{Ticket}->CurrentUser);
+                my ($ret, $msg) = $role_values->LoadRoleGroup(Object => $args{Ticket}, Name => $role);
+                push @errors, $CurrentUser->loc("Failed to load role $role for ticket: $msg") unless $ret;
+                return \@errors unless $ret;
+            }
+
+            my @role_values;
+            my @row_input_id = grep $role_arg eq $ARGSRef->{$_}, keys %{$ARGSRef};
+            if ( @row_input_id ) {
+                map {push @role_values, $ARGSRef->{"WatcherAddressEmail$_"} } grep { $_ =~ qr/WatcherTypeEmail(.+)/ } @row_input_id;
+            }
+
+            my @temp_array = $role_values->MemberEmailAddresses;
+            push @role_values, @temp_array if scalar @temp_array;
+
+            if ( not scalar @role_values ) {
+                    push @errors, "Requires value for $role to perform action.";
+                    return \@errors;
+            }
+        return \@errors if scalar @errors;
+    }
+
     return \@errors unless @$cfs;
 
     if ( not $CFs ){
@@ -565,7 +636,7 @@ sub CheckMandatoryFields {
         }
 
         # Check for specific values
-        if ( exists $must_values->{$cf->Name} ){
+        if ( exists $cf_must_values->{$cf->Name} ){
             my $cf_value = $value;
 
             if ( not defined $cf_value and $args{'Ticket'} ){
@@ -574,8 +645,8 @@ sub CheckMandatoryFields {
                 $cf_value = $args{'Ticket'}->FirstCustomFieldValue($cf->Name);
             }
 
-            if ( exists $must_values->{$cf->Name}{'must_be'} ){
-                my @must_be = @{$must_values->{$cf->Name}{'must_be'}};
+            if ( exists $cf_must_values->{$cf->Name}{'must_be'} ){
+                my @must_be = @{$cf_must_values->{$cf->Name}{'must_be'}};
 
                 # OK if it's defined and is one of the specified values
                 next if defined $cf_value and grep { $cf_value eq $_ } @must_be;
@@ -593,8 +664,8 @@ sub CheckMandatoryFields {
                 next;
             }
 
-            if ( exists $must_values->{$cf->Name}{'must_not_be'} ){
-                my @must_not_be = @{$must_values->{$cf->Name}{'must_not_be'}};
+            if ( exists $cf_must_values->{$cf->Name}{'must_not_be'} ){
+                my @must_not_be = @{$cf_must_values->{$cf->Name}{'must_not_be'}};
 
                 # OK if it's defined and _not_ in the list
                 next if defined $cf_value and !grep { $cf_value eq $_ } @must_not_be;

commit 609d0c3d66ddd2615a7e81b23aab21ad37355bcc
Author: Craig Kaiser <craig at bestpractical.com>
Date:   Fri Jan 4 14:33:30 2019 -0500

    Allow group key to be set for roles
    
    If a group key is set for a role it will be attempted
    to be loaded and then check that a value for the
    role is a member of the group.

diff --git a/lib/RT/Extension/MandatoryOnTransition.pm b/lib/RT/Extension/MandatoryOnTransition.pm
index 3786e81..661e923 100644
--- a/lib/RT/Extension/MandatoryOnTransition.pm
+++ b/lib/RT/Extension/MandatoryOnTransition.pm
@@ -567,7 +567,30 @@ sub CheckMandatoryFields {
             if ( not scalar @role_values ) {
                     push @errors, "Requires value for $role to perform action.";
                     return \@errors;
+            } elsif ( $role_group_values->{$role_full}->{group} ) {
+                my $group_name = $role_group_values->{$role_full}->{group};
+                my $group = RT::Group->new($args{Ticket}->CurrentUser);
+
+                my ($ret, $msg) = $group->LoadUserDefinedGroup($group_name);
+                push @errors, $CurrentUser->loc("Failed to load group: '$group_name' $msg") unless $ret;
+                return \@errors unless $ret;
+
+                my $has_valid_member;
+                my $user = RT::User->new($args{Ticket}->CurrentUser);
+
+                foreach my $member (@role_values) {
+                    next if $has_valid_member;
+                    ($ret, $msg) = $user->LoadByEmail($member);
+                    RT::Logger->error($msg) unless $ret;
+                    next unless $ret;
+
+                    $has_valid_member = $group->HasMemberRecursively($user->Id);
+                }
+                push @errors, $CurrentUser->loc("User who is a member of $group_name is required for role: $role")
+                    unless $has_valid_member;
+                return \@errors unless $has_valid_member;
             }
+        }
         return \@errors if scalar @errors;
     }
 

-----------------------------------------------------------------------


More information about the Bps-public-commit mailing list