[Bps-public-commit] rt-extension-automaticassignment branch, master, updated. a39e42c4414505330141067397403c5d02d928d0

Shawn Moore shawn at bestpractical.com
Tue Aug 2 16:48:59 EDT 2016


The branch, master has been updated
       via  a39e42c4414505330141067397403c5d02d928d0 (commit)
       via  1c1cf0d77585e10052a0eaf9c9175939395d69fc (commit)
       via  5993b2d9166cc9ec8cad94f60cd471953c17815e (commit)
       via  458ad0735870a2e67059b3f6617e1d49ad193942 (commit)
      from  8f27e17a38d66f1941862fb91cb7fad97e9cd392 (commit)

Summary of changes:
 META.yml                                           |  1 +
 Makefile.PL                                        |  2 +
 lib/RT/CustomFieldValues/ServiceBusinessHours.pm   | 56 +++++++++++++
 lib/RT/Extension/AutomaticAssignment.pm            | 32 +++++++-
 lib/RT/Extension/AutomaticAssignment/Filter.pm     |  4 +
 .../AutomaticAssignment/Filter/BusinessHours.pm    | 95 ++++++++++++++++++++++
 6 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 lib/RT/CustomFieldValues/ServiceBusinessHours.pm
 create mode 100644 lib/RT/Extension/AutomaticAssignment/Filter/BusinessHours.pm

- Log -----------------------------------------------------------------
commit 458ad0735870a2e67059b3f6617e1d49ad193942
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Aug 2 19:44:00 2016 +0000

    Add a way for filters to take an arrayref of users
    
        Not all the filtering we want to do can be done in SearchBuilder!

diff --git a/lib/RT/Extension/AutomaticAssignment.pm b/lib/RT/Extension/AutomaticAssignment.pm
index 6f44163..2e58333 100644
--- a/lib/RT/Extension/AutomaticAssignment.pm
+++ b/lib/RT/Extension/AutomaticAssignment.pm
@@ -37,7 +37,29 @@ sub _EligibleOwnersForTicket {
         }
         else {
             my $class = $filter->{class};
-            $class->FilterOwnersForTicket($ticket, $users, $filter);
+            $class->FilterOwnersForTicket($ticket, $users, $filter)
+                if !$class->FiltersUsersArray;
+        }
+    }
+
+    return $users;
+}
+
+sub _FilterUsersArrayForTicket {
+    my $self   = shift;
+    my $ticket = shift;
+    my $users  = shift;
+    my $config = shift;
+
+    for my $filter (@{ $config->{filters} }) {
+        if (ref($filter) eq 'CODE') {
+            next;
+        }
+        else {
+            my $class = $filter->{class};
+            next unless $class->FiltersUsersArray;
+
+            $users = $class->FilterOwnersForTicket($ticket, $users, $filter);
         }
     }
 
@@ -128,6 +150,9 @@ sub OwnerForTicket {
     );
 
     my @users = @{ $users->ItemsArrayRef };
+
+    @users = @{ $self->_FilterUsersArrayForTicket($ticket, \@users, $config) };
+
     my $user = $self->_ChooseOwnerForTicket($ticket, \@users, $config);
 
     return $user;
diff --git a/lib/RT/Extension/AutomaticAssignment/Filter.pm b/lib/RT/Extension/AutomaticAssignment/Filter.pm
index b08f68f..88d9bb5 100644
--- a/lib/RT/Extension/AutomaticAssignment/Filter.pm
+++ b/lib/RT/Extension/AutomaticAssignment/Filter.pm
@@ -8,6 +8,10 @@ sub FilterOwnersForTicket {
     die "Subclass " . ref($self) . " of " . __PACKAGE__ . " does not implement required method FilterOwnersForTicket";
 }
 
+sub FiltersUsersArray {
+    return 0;
+}
+
 1;
 
 

commit 5993b2d9166cc9ec8cad94f60cd471953c17815e
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Aug 2 20:11:31 2016 +0000

    Explicitly exclude RT System and Nobody from automatic assignment

diff --git a/lib/RT/Extension/AutomaticAssignment.pm b/lib/RT/Extension/AutomaticAssignment.pm
index 2e58333..71726e3 100644
--- a/lib/RT/Extension/AutomaticAssignment.pm
+++ b/lib/RT/Extension/AutomaticAssignment.pm
@@ -30,6 +30,11 @@ sub _EligibleOwnersForTicket {
     my $config = shift;
 
     my $users = RT::Users->new(RT->SystemUser);
+    $users->Limit(
+        FIELD    => 'id',
+        OPERATOR => 'NOT IN',
+        VALUE    => [ RT->System->id, RT->Nobody->id ],
+    );
 
     for my $filter (@{ $config->{filters} }) {
         if (ref($filter) eq 'CODE') {

commit 1c1cf0d77585e10052a0eaf9c9175939395d69fc
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Aug 2 20:36:38 2016 +0000

    Add BusinessHours filter

diff --git a/META.yml b/META.yml
index 0b72455..27bacfc 100644
--- a/META.yml
+++ b/META.yml
@@ -19,6 +19,7 @@ no_index:
     - etc
     - inc
 requires:
+  Business::Hours: 0
   perl: 5.8.3
 resources:
   license: http://opensource.org/licenses/gpl-license.php
diff --git a/Makefile.PL b/Makefile.PL
index bd2131c..1207c3a 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -2,6 +2,8 @@ use inc::Module::Install;
 
 RTx 'RT-Extension-AutomaticAssignment';
 
+requires 'Business::Hours';
+
 requires_rt '4.2';
 rt_too_new '4.6';
 
diff --git a/lib/RT/Extension/AutomaticAssignment/Filter/BusinessHours.pm b/lib/RT/Extension/AutomaticAssignment/Filter/BusinessHours.pm
new file mode 100644
index 0000000..c137e7a
--- /dev/null
+++ b/lib/RT/Extension/AutomaticAssignment/Filter/BusinessHours.pm
@@ -0,0 +1,95 @@
+package RT::Extension::AutomaticAssignment::Filter::BusinessHours;
+use strict;
+use warnings;
+use base 'RT::Extension::AutomaticAssignment::Filter';
+use Business::Hours;
+
+sub _UserCF {
+    my $class = shift;
+    my $name = shift;
+
+    my $cf = RT::CustomField->new(RT->SystemUser);
+    $cf->LoadByName(
+        Name       => $name,
+        LookupType => RT::User->CustomFieldLookupType,
+    );
+    if (!$cf->Id) {
+        die "Unable to load User Custom Field named '$name'";
+    }
+    return $cf;
+}
+
+sub _IsTimeWithinBusinessHours {
+    my $class  = shift;
+    my $time   = shift;
+    my $config = shift;
+    my $tz     = shift || $RT::Timezone;
+
+    # closely modeled off of RT::SLA
+
+    my $res = 0;
+
+    my $ok = eval {
+        local $ENV{'TZ'} = $ENV{'TZ'};
+
+        if ($tz && $tz ne ($ENV{'TZ'}||'') ) {
+            $ENV{'TZ'} = $tz;
+            require POSIX; POSIX::tzset();
+        }
+
+        my $hours = Business::Hours->new;
+        $hours->business_hours(%$config);
+
+        $res = ($hours->first_after($time) == $time);
+
+        1;
+    };
+
+    POSIX::tzset() if $tz && $tz ne ($ENV{'TZ'}||'');
+    die $@ unless $ok;
+
+    return $res;
+}
+
+sub FiltersUsersArray {
+    return 1;
+}
+
+sub FilterOwnersForTicket {
+    my $class  = shift;
+    my $ticket = shift;
+    my $users  = shift;
+    my $config = shift;
+
+    my $now = time;
+
+    if ($config->{user_cf}) {
+        $class->_UserCF($config->{user_cf}); # validate user CF exists
+
+        my @eligible;
+        for my $user (@$users) {
+            my $schedule = $user->FirstCustomFieldValue($config->{user_cf});
+            if (!$schedule) {
+                RT->Logger->debug("No value for user CF '$config->{user_cf}' for user " . $user->Name . "; skipping from BusinessHours automatic assignment");
+                next;
+            }
+
+            my $args = $RT::ServiceBusinessHours{$schedule};
+            if (!$args) {
+                die "No ServiceBusinessHours config defined for schedule named '$schedule' for user " . $user->Name;
+            }
+
+            my $tz = $config->{user_tz} ? $user->Timezone : $RT::Timezone;
+
+            push @eligible, $user
+                if $class->_IsTimeWithinBusinessHours($now, $args, $tz);
+        }
+        return \@eligible;
+    }
+    else {
+        die "Unable to filter BusinessHours; no 'user_cf' provided.";
+    }
+}
+
+1;
+

commit a39e42c4414505330141067397403c5d02d928d0
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Aug 2 20:36:46 2016 +0000

    Add ServiceBusinessHours customfieldvalues source

diff --git a/lib/RT/CustomFieldValues/ServiceBusinessHours.pm b/lib/RT/CustomFieldValues/ServiceBusinessHours.pm
new file mode 100644
index 0000000..b4adc0b
--- /dev/null
+++ b/lib/RT/CustomFieldValues/ServiceBusinessHours.pm
@@ -0,0 +1,56 @@
+package RT::CustomFieldValues::ServiceBusinessHours;
+use strict;
+use warnings;
+
+use base qw(RT::CustomFieldValues::External);
+
+=head1 NAME
+
+RT::CustomFieldValues::Groups - Provide RT's %ServiceBusinessHours as a dynamic list of CF values
+
+=head1 SYNOPSIS
+
+To use as a source of CF values, add the following to your F<RT_SiteConfig.pm>
+and restart RT.
+
+    # In RT_SiteConfig.pm
+    Set( @CustomFieldValuesSources, "RT::CustomFieldValues::ServiceBusinessHours" );
+
+Then visit the modify CF page in the RT admin configuration.
+
+=head1 METHODS
+
+Most methods are inherited from L<RT::CustomFieldValues::External>, except the
+ones below.
+
+=head2 SourceDescription
+
+Returns a brief string describing this data source.
+
+=cut
+
+sub SourceDescription {
+    return 'RT service business hours';
+}
+
+=head2 ExternalValues
+
+Returns an arrayref containing a hashref for each possible value in this data
+source, where the value name is the service business hours name.
+
+=cut
+
+sub ExternalValues {
+    my $self = shift;
+
+    my @res;
+    for my $name (sort keys %RT::ServiceBusinessHours) {
+        push @res, {
+            name => $name,
+        };
+    }
+    return \@res;
+}
+
+1;
+

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


More information about the Bps-public-commit mailing list