From 73348c187f0946b6e13355b973c14ea53d284330 Mon Sep 17 00:00:00 2001
From: Peter Rotich <peter@osticket.com>
Date: Wed, 4 Mar 2015 22:48:29 +0000
Subject: [PATCH] Assignment Field

Add support for passing a criteria to AssignmentField to limit  the choices
Limit assignees based on department settings
Cache choices
---
 include/class.dept.php  |  1 +
 include/class.forms.php | 79 ++++++++++++++++++++++++++++++++++++-----
 include/class.staff.php |  7 ++--
 3 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/include/class.dept.php b/include/class.dept.php
index 43a98692d..8343d6f66 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -175,6 +175,7 @@ implements TemplateVariable {
                     'onvacation' => 0,
                 ));
 
+            $members->distinct('staff_id');
             switch ($cfg->getDefaultNameFormat()) {
             case 'last':
             case 'lastfirst':
diff --git a/include/class.forms.php b/include/class.forms.php
index 6e7de311d..3b532cca6 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -1241,6 +1241,7 @@ class BooleanField extends FormField {
 
 class ChoiceField extends FormField {
     static $widget = 'ChoicesWidget';
+    var $_choices;
 
     function getConfigurationOptions() {
         return array(
@@ -1316,6 +1317,18 @@ class ChoiceField extends FormField {
         return (string) $value;
     }
 
+    /*
+     Return criteria to which the choice should be filtered by
+     */
+    function getCriteria() {
+        $config = $this->getConfiguration();
+        $criteria = array();
+        if (isset($config['criteria']))
+            $criteria = $config['criteria'];
+
+        return $criteria;
+    }
+
     function getChoice($value) {
 
         $choices = $this->getChoices();
@@ -1796,6 +1809,9 @@ FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
 
 
 class AssigneeField extends ChoiceField {
+    var $_choices = array();
+    var $_criteria = null;
+
     function getWidget() {
         $widget = parent::getWidget();
         if (is_object($widget->value))
@@ -1803,27 +1819,62 @@ class AssigneeField extends ChoiceField {
         return $widget;
     }
 
+    function getCriteria() {
+
+        if (!isset($this->_criteria)) {
+            $this->_criteria = array('available' => true);
+            if (($c=parent::getCriteria()))
+                $this->_criteria = array_merge($this->_criteria, $c);
+        }
+
+        return $this->_criteria;
+    }
+
     function hasIdValue() {
         return true;
     }
 
     function getChoices() {
         global $cfg;
-        $choices = array(__('Agents') => new ArrayObject(), __('Teams') => new ArrayObject());
-        $A = current($choices);
-        if (($agents = Staff::getAvailableStaffMembers()))
+
+        if (!$this->_choices) {
+            $config = $this->getConfiguration();
+            $choices = array(
+                    __('Agents') => new ArrayObject(),
+                    __('Teams') => new ArrayObject());
+            $A = current($choices);
+            $criteria = $this->getCriteria();
+            $agents = array();
+            if (($dept=$config['dept']) && $dept->assignMembersOnly()) {
+                if (($members = $dept->getMembers($criteria)))
+                    foreach ($members as $member)
+                        $agents[$member->getId()] = $member;
+            } else {
+                $agents = Staff::getStaffMembers($criteria);
+            }
+
             foreach ($agents as $id => $name)
                 $A['s'.$id] = $name;
 
-        next($choices);
-        $T = current($choices);
-        if (($teams = Team::getTeams()))
-            foreach ($teams as $id => $name)
-                $T['t'.$id] = $name;
+            next($choices);
+            $T = current($choices);
+            if (($teams = Team::getTeams()))
+                foreach ($teams as $id => $name)
+                    $T['t'.$id] = $name;
 
-        return $choices;
+            $this->_choices = $choices;
+        }
+
+        return $this->_choices;
     }
 
+    function getValue() {
+
+        if (($value = parent::getValue()) && ($id=$this->getClean()))
+           return $value[$id];
+    }
+
+
     function parse($id) {
         return $this->to_php(null, $id);
     }
@@ -3205,9 +3256,13 @@ class AssignmentForm extends Form {
 
     static $id = 'assign';
     var $_assignee = null;
+    var $_dept = null;
 
     function __construct($source=null, $options=array()) {
         parent::__construct($source, $options);
+        // Department of the object -- if necessary to limit assinees
+        if (isset($options['dept']))
+            $this->_dept = $options['dept'];
     }
 
     function getFields() {
@@ -3222,6 +3277,12 @@ class AssignmentForm extends Form {
                     'flags' => hexdec(0X450F3),
                     'required' => true,
                     'validator-error' => __('Assignee selection required'),
+                    'configuration' => array(
+                        'criteria' => array(
+                            'available' => true,
+                            ),
+                        'dept' => $this->_dept ?: null,
+                       ),
                     )
                 ),
             'comments' => new TextareaField(array(
diff --git a/include/class.staff.php b/include/class.staff.php
index bcd3ed16f..b295a15e1 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -697,11 +697,12 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
             return null;
     }
 
-    static function getStaffMembers($availableonly=false) {
+    static function getStaffMembers($criteria=array()) {
         global $cfg;
+
         $members = static::objects();
 
-        if ($availableonly) {
+        if (isset($criteria['available'])) {
             $members = $members->filter(array(
                 'group__flags__hasbit' => Group::FLAG_ENABLED,
                 'onvacation' => 0,
@@ -729,7 +730,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable {
     }
 
     static function getAvailableStaffMembers() {
-        return self::getStaffMembers(true);
+        return self::getStaffMembers(array('available'=>true));
     }
 
     static function getIdByUsername($username) {
-- 
GitLab