Skip to content

Commit

Permalink
dev/core#107 Refactor selection of default assignee by relationship type
Browse files Browse the repository at this point in the history
  • Loading branch information
reneolivo committed Jun 28, 2018
1 parent e250519 commit 4f54a18
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 57 deletions.
50 changes: 43 additions & 7 deletions CRM/Case/XMLProcessor/Process.php
Expand Up @@ -640,29 +640,65 @@ protected function getDefaultAssigneeOptionValues() {
* @return int|null the ID of the default assignee contact or null if none.
*/
protected function getDefaultAssigneeByRelationship($activityParams, $activityTypeXML) {
if (!isset($activityTypeXML->default_assignee_relationship)) {
$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);

$relationships = civicrm_api3('Relationship', 'get', [
'contact_id_b' => $targetContactId,
'relationship_type_id.name_b_a' => (string) $activityTypeXML->default_assignee_relationship,
$params = [
'relationship_type_id' => $relTypeId,
"contact_id_$b" => $targetContactId,
'is_active' => 1,
'sequential' => 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']) {
return $relationships['values'][0]['contact_id_a'];
$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.
Expand Down
23 changes: 23 additions & 0 deletions ang/crmCaseType.js
Expand Up @@ -264,11 +264,34 @@
$scope.relationshipTypeOptions = _.map(apiCalls.relTypes.values, function(type) {
return {id: type[REL_TYPE_CNAME], text: type.label_b_a};
});
$scope.defaultRelationshipTypeOptions = getDefaultRelationshipTypeOptions();
// stores the default assignee values indexed by their option name:
$scope.defaultAssigneeTypeValues = _.chain($scope.defaultAssigneeTypes)
.indexBy('name').mapValues('value').value();
}

/// Returns the default relationship type options. If the relationship is
/// bidirectional (Ex: Spouse of) it adds a single option otherwise it adds
/// two options representing the relationship type directions
/// (Ex: Employee of, Employer is)
function getDefaultRelationshipTypeOptions() {
return _.transform(apiCalls.relTypes.values, function(result, relType) {
var isBidirectionalRelationship = relType.label_a_b === relType.label_b_a;

result.push({
label: relType.label_b_a,
value: relType.id + '_b_a'
});

if (!isBidirectionalRelationship) {
result.push({
label: relType.label_a_b,
value: relType.id + '_a_b'
});
}
}, []);
}

/// initializes the case type object
function initCaseType() {
var isNewCaseType = !apiCalls.caseType;
Expand Down
2 changes: 1 addition & 1 deletion ang/crmCaseType/timelineTable.html
Expand Up @@ -76,7 +76,7 @@
ui-jq="select2"
ui-options="{dropdownAutoWidth: true}"
ng-model="activity.default_assignee_relationship"
ng-options="option.id as option.text for option in relationshipTypeOptions"
ng-options="option.value as option.label for option in defaultRelationshipTypeOptions"
required
></select>
</p>
Expand Down
32 changes: 32 additions & 0 deletions tests/karma/unit/crmCaseTypeSpec.js
Expand Up @@ -188,6 +188,18 @@ describe('crmCaseType', function() {
"contact_type_b": "Individual",
"is_reserved": "0",
"is_active": "1"
},
{
"id": "2",
"name_a_b": "Spouse of",
"label_a_b": "Spouse of",
"name_b_a": "Spouse of",
"label_b_a": "Spouse of",
"description": "Spousal relationship.",
"contact_type_a": "Individual",
"contact_type_b": "Individual",
"is_reserved": "0",
"is_active": "1"
}
]
},
Expand Down Expand Up @@ -314,6 +326,26 @@ describe('crmCaseType', function() {
expect(scope.defaultAssigneeTypeValues).toEqual(defaultAssigneeTypeValues);
});

it('should store the default assignee relationship type options', function() {
var defaultRelationshipTypeOptions = _.transform(apiCalls.relTypes.values, function(result, relType) {
var isBidirectionalRelationship = relType.label_a_b === relType.label_b_a;

result.push({
label: relType.label_b_a,
value: relType.id + '_b_a'
});

if (!isBidirectionalRelationship) {
result.push({
label: relType.label_a_b,
value: relType.id + '_a_b'
});
}
}, []);

expect(scope.defaultRelationshipTypeOptions).toEqual(defaultRelationshipTypeOptions);
});

it('addActivitySet should add an activitySet to the case type', function() {
scope.addActivitySet('timeline');
var activitySets = scope.caseType.definition.activitySets;
Expand Down

0 comments on commit 4f54a18

Please sign in to comment.