Skip to content

Commit

Permalink
PCHR-3935: Add default assignee configuration for Case Types
Browse files Browse the repository at this point in the history
Included in 5.4.0
Core PR: civicrm#11998
  • Loading branch information
reneolivo committed Jul 24, 2018
1 parent 46e5449 commit 69b4515
Show file tree
Hide file tree
Showing 5 changed files with 489 additions and 47 deletions.
157 changes: 157 additions & 0 deletions CRM/Case/XMLProcessor/Process.php
Expand Up @@ -31,6 +31,8 @@
* @copyright CiviCRM LLC (c) 2004-2018
*/
class CRM_Case_XMLProcessor_Process extends CRM_Case_XMLProcessor {
protected $defaultAssigneeOptionsValues = [];

/**
* Run.
*
Expand Down Expand Up @@ -314,6 +316,7 @@ public function activityTypes($activityTypesXML, $maxInst = FALSE, $isLabel = FA

/**
* @param SimpleXMLElement $caseTypeXML
*
* @return array<string> symbolic activity-type names
*/
public function getDeclaredActivityTypes($caseTypeXML) {
Expand Down Expand Up @@ -342,6 +345,7 @@ public function getDeclaredActivityTypes($caseTypeXML) {

/**
* @param SimpleXMLElement $caseTypeXML
*
* @return array<string> symbolic relationship-type names
*/
public function getDeclaredRelationshipTypes($caseTypeXML) {
Expand Down Expand Up @@ -474,6 +478,8 @@ public function createActivity($activityTypeXML, &$params) {
);
}

$activityParams['assignee_contact_id'] = $this->getDefaultAssigneeForActivity($activityParams, $activityTypeXML);

//parsing date to default preference format
$params['activity_date_time'] = CRM_Utils_Date::processDate($params['activity_date_time']);

Expand Down Expand Up @@ -568,6 +574,155 @@ public function createActivity($activityTypeXML, &$params) {
return TRUE;
}

/**
* Return the default assignee contact for the activity.
*
* @param array $activityParams
* @param object $activityTypeXML
*
* @return int|null the ID of the default assignee contact or null if none.
*/
protected function getDefaultAssigneeForActivity($activityParams, $activityTypeXML) {
if (!isset($activityTypeXML->default_assignee_type)) {
return NULL;
}

$defaultAssigneeOptionsValues = $this->getDefaultAssigneeOptionValues();

switch ($activityTypeXML->default_assignee_type) {
case $defaultAssigneeOptionsValues['BY_RELATIONSHIP']:
return $this->getDefaultAssigneeByRelationship($activityParams, $activityTypeXML);

break;
case $defaultAssigneeOptionsValues['SPECIFIC_CONTACT']:
return $this->getDefaultAssigneeBySpecificContact($activityTypeXML);

break;
case $defaultAssigneeOptionsValues['USER_CREATING_THE_CASE']:
return $activityParams['source_contact_id'];

break;
case $defaultAssigneeOptionsValues['NONE']:
default:
return NULL;
}
}

/**
* Fetches and caches the activity's default assignee options.
*
* @return array
*/
protected function getDefaultAssigneeOptionValues() {
if (!empty($this->defaultAssigneeOptionsValues)) {
return $this->defaultAssigneeOptionsValues;
}

$defaultAssigneeOptions = civicrm_api3('OptionValue', 'get', [
'option_group_id' => 'activity_default_assignee',
'options' => [ 'limit' => 0 ]
]);

foreach ($defaultAssigneeOptions['values'] as $option) {
$this->defaultAssigneeOptionsValues[$option['name']] = $option['value'];
}

return $this->defaultAssigneeOptionsValues;
}

/**
* Returns the default assignee for the activity by searching for the target's
* contact relationship type defined in the activity's details.
*
* @param array $activityParams
* @param object $activityTypeXML
*
* @return int|null the ID of the default assignee contact or null if none.
*/
protected function getDefaultAssigneeByRelationship($activityParams, $activityTypeXML) {
$isDefaultRelationshipDefined = isset($activityTypeXML->default_assignee_relationship)
&& preg_match('/\d+_[ab]_[ab]/', $activityTypeXML->default_assignee_relationship);

if (!$isDefaultRelationshipDefined) {
return NULL;
}

$targetContactId = is_array($activityParams['target_contact_id'])
? CRM_Utils_Array::first($activityParams['target_contact_id'])
: $activityParams['target_contact_id'];
list($relTypeId, $a, $b) = explode('_', $activityTypeXML->default_assignee_relationship);

$params = [
'relationship_type_id' => $relTypeId,
"contact_id_$b" => $targetContactId,
'is_active' => 1,
];

if ($this->isBidirectionalRelationshipType($relTypeId)) {
$params["contact_id_$a"] = $targetContactId;
$params['options']['or'] = [['contact_id_a', 'contact_id_b']];
}

$relationships = civicrm_api3('Relationship', 'get', $params);

if ($relationships['count']) {
$relationship = CRM_Utils_Array::first($relationships['values']);

// returns the contact id on the other side of the relationship:
return (int) $relationship['contact_id_a'] === (int) $targetContactId
? $relationship['contact_id_b']
: $relationship['contact_id_a'];
}
else {
return NULL;
}
}

/**
* Determines if the given relationship type is bidirectional or not by
* comparing their labels.
*
* @return bool
*/
protected function isBidirectionalRelationshipType($relationshipTypeId) {
$relationshipTypeResult = civicrm_api3('RelationshipType', 'get', [
'id' => $relationshipTypeId,
'options' => ['limit' => 1]
]);

if ($relationshipTypeResult['count'] === 0) {
return FALSE;
}

$relationshipType = CRM_Utils_Array::first($relationshipTypeResult['values']);

return $relationshipType['label_b_a'] === $relationshipType['label_a_b'];
}

/**
* Returns the activity's default assignee for a specific contact if the contact exists,
* otherwise returns null.
*
* @param object $activityTypeXML
*
* @return int|null
*/
protected function getDefaultAssigneeBySpecificContact($activityTypeXML) {
if (!$activityTypeXML->default_assignee_contact) {
return NULL;
}

$contact = civicrm_api3('Contact', 'get', [
'id' => $activityTypeXML->default_assignee_contact
]);

if ($contact['count'] == 1) {
return $activityTypeXML->default_assignee_contact;
}

return NULL;
}

/**
* @param $activitySetsXML
*
Expand Down Expand Up @@ -617,6 +772,7 @@ public function getCaseManagerRoleId($caseType) {

/**
* @param string $caseType
*
* @return array<\Civi\CCase\CaseChangeListener>
*/
public function getListeners($caseType) {
Expand Down Expand Up @@ -662,6 +818,7 @@ public function getNaturalActivityTypeSort() {
* @param string $settingKey
* @param string $xmlTag
* @param mixed $default
*
* @return int
*/
private function getBoolSetting($settingKey, $xmlTag, $default = 0) {
Expand Down
15 changes: 11 additions & 4 deletions CRM/Core/BAO/OptionValue.php
Expand Up @@ -547,16 +547,23 @@ public static function getOptionValuesAssocArrayFromName($optionGroupName) {
* that an option value exists, without hitting an error if it already exists.
*
* This is sympathetic to sites who might pre-add it.
*
* @param array $params the option value attributes.
* @return array the option value attributes.
*/
public static function ensureOptionValueExists($params) {
$existingValues = civicrm_api3('OptionValue', 'get', array(
$result = civicrm_api3('OptionValue', 'get', array(
'option_group_id' => $params['option_group_id'],
'name' => $params['name'],
'return' => 'id',
'return' => ['id', 'value'],
'sequential' => 1,
));
if (!$existingValues['count']) {
civicrm_api3('OptionValue', 'create', $params);

if (!$result['count']) {
$result = civicrm_api3('OptionValue', 'create', $params);
}

return CRM_Utils_Array::first($result['values']);
}

}

0 comments on commit 69b4515

Please sign in to comment.