Skip to content

Commit

Permalink
Merge pull request #15570 from colemanw/caseRoles
Browse files Browse the repository at this point in the history
Restrict case roles by group
  • Loading branch information
seamuslee001 authored Jan 11, 2020
2 parents 094d53f + c4bfbde commit c4a019b
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 29 deletions.
16 changes: 13 additions & 3 deletions CRM/Case/BAO/CaseType.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public static function convertDefinitionToXML($name, $definition) {
foreach ($definition['caseRoles'] as $values) {
$xmlFile .= "<RelationshipType>\n";
foreach ($values as $key => $value) {
$xmlFile .= "<{$key}>" . self::encodeXmlString($value) . "</{$key}>\n";
$xmlFile .= "<{$key}>" . ($key == 'groups' ? implode(',', array_map(['\CRM_Case_BAO_CaseType', 'encodeXmlString'], (array) $value)) : self::encodeXmlString($value)) . "</{$key}>\n";
}
$xmlFile .= "</RelationshipType>\n";
}
Expand All @@ -180,7 +180,7 @@ public static function convertDefinitionToXML($name, $definition) {

if (!empty($definition['activityAsgmtGrps'])) {
$xmlFile .= "<ActivityAsgmtGrps>\n";
foreach ($definition['activityAsgmtGrps'] as $value) {
foreach ((array) $definition['activityAsgmtGrps'] as $value) {
$xmlFile .= "<Group>$value</Group>\n";
}
$xmlFile .= "</ActivityAsgmtGrps>\n";
Expand Down Expand Up @@ -234,6 +234,12 @@ public static function convertXmlToDefinition($xml) {

if (isset($xml->ActivityAsgmtGrps)) {
$definition['activityAsgmtGrps'] = (array) $xml->ActivityAsgmtGrps->Group;
// Backwards compat - convert group ids to group names if ids are supplied
if (array_filter($definition['activityAsgmtGrps'], ['\CRM_Utils_Rule', 'integer']) === $definition['activityAsgmtGrps']) {
foreach ($definition['activityAsgmtGrps'] as $idx => $group) {
$definition['activityAsgmtGrps'][$idx] = CRM_Core_DAO::getFieldValue('CRM_Contact_BAO_Group', $group);
}
}
}

// set activity types
Expand Down Expand Up @@ -284,7 +290,11 @@ public static function convertXmlToDefinition($xml) {
if (isset($xml->CaseRoles)) {
$definition['caseRoles'] = [];
foreach ($xml->CaseRoles->RelationshipType as $caseRoleXml) {
$definition['caseRoles'][] = json_decode(json_encode($caseRoleXml), TRUE);
$caseRole = json_decode(json_encode($caseRoleXml), TRUE);
if (!empty($caseRole['groups'])) {
$caseRole['groups'] = explode(',', $caseRole['groups']);
}
$definition['caseRoles'][] = $caseRole;
}
}

Expand Down
22 changes: 21 additions & 1 deletion CRM/Case/Form/CaseView.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,31 @@ public function buildQuickForm() {
}

$allowedRelationshipTypes = CRM_Contact_BAO_Relationship::getContactRelationshipType($this->_contactID);
$relationshipTypeMetadata = CRM_Contact_Form_Relationship::getRelationshipTypeMetadata($allowedRelationshipTypes);

$caseTypeDefinition = civicrm_api3('CaseType', 'getsingle', ['name' => $this->_caseType])['definition'];

foreach ($caseTypeDefinition['caseRoles'] as $role) {
if (!empty($role['groups'])) {
$relationshipType = civicrm_api3('RelationshipType', 'get', [
'sequential' => 1,
'name_a_b' => $role['name'],
'name_b_a' => $role['name'],
'options' => ['limit' => 1, 'or' => [["name_a_b", "name_b_a"]]],
]);
if (($relationshipType['values'][0]['name_a_b'] ?? NULL) === $role['name']) {
$relationshipTypeMetadata[$relationshipType['id']]['group_a'] = $role['groups'];
}
if (($relationshipType['values'][0]['name_b_a'] ?? NULL) === $role['name']) {
$relationshipTypeMetadata[$relationshipType['id']]['group_b'] = $role['groups'];
}
}
}

CRM_Core_Resources::singleton()
->addScriptFile('civicrm', 'js/crm.livePage.js', 1, 'html-header')
->addScriptFile('civicrm', 'templates/CRM/Case/Form/CaseView.js', 2, 'html-header')
->addVars('relationshipTypes', CRM_Contact_Form_Relationship::getRelationshipTypeMetadata($allowedRelationshipTypes));
->addVars('relationshipTypes', $relationshipTypeMetadata);

$xmlProcessor = new CRM_Case_XMLProcessor_Process();
$caseRoles = $xmlProcessor->get($this->_caseType, 'CaseRoles');
Expand Down
2 changes: 1 addition & 1 deletion ang/crmCaseType/caseTypeDetails.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<input
name="activityAsgmtGrps"
crm-ui-id="caseTypeDetailForm.activityAsgmtGrps"
crm-entityref="{entity: 'Group', api: {params: {is_hidden: 0, is_active: 1}}, select: {allowClear: true, multiple: true, placeholder: ts('Select Group')}}"
crm-entityref="{entity: 'Group', api: {id_field: 'name', params: {is_hidden: 0, is_active: 1}}, select: {allowClear: true, multiple: true, placeholder: ts('Select Group')}}"
ng-model="caseType.definition.activityAsgmtGrps"
/>
</div>
Expand Down
5 changes: 5 additions & 0 deletions ang/crmCaseType/rolesTable.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<th>{{ts('Display Label')}}</th>
<th>{{ts('Assign to Creator')}}</th>
<th>{{ts('Is Manager')}}</th>
<th>{{ts('Restrict to Groups')}}</th>
<th></th>
</tr>
</thead>
Expand All @@ -17,6 +18,10 @@
<td>{{relType.displayLabel}}</td>
<td><input type="checkbox" ng-model="relType.creator" ng-true-value="'1'" ng-false-value="'0'"></td>
<td><input type="radio" ng-model="relType.manager" value="1" ng-change="onManagerChange(relType)"></td>
<td><input ng-list class="big"
crm-entityref="{entity: 'Group', api: {id_field: 'name', params: {is_hidden: 0, is_active: 1}}, select: {allowClear: true, multiple: true, placeholder: ts('Select Group')}}"
ng-model="relType.groups"
/></td>
<td>
<a crm-icon="fa-trash" class="crm-hover-button" ng-click="removeItem(caseType.definition.caseRoles,relType)" title="{{ts('Remove')}}"></a>
</td>
Expand Down
52 changes: 28 additions & 24 deletions templates/CRM/Case/Form/CaseView.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,29 +73,12 @@
var val = $(this).val();
$contactField.val('').change().prop('disabled', !val);
if (val) {
var
pieces = val.split('_'),
rType = pieces[0],
target = pieces[2], // b or a
contact_type = CRM.vars.relationshipTypes[rType]['contact_type_' + target],
contact_sub_type = CRM.vars.relationshipTypes[rType]['contact_sub_type_' + target],
api = {params: {}};
if (contact_type) {
api.params.contact_type = contact_type;
}
if (contact_sub_type) {
api.params.contact_sub_type = contact_sub_type;
}
$contactField
.data('api-params', api)
.data('user-filter', {})
.attr('placeholder', CRM.vars.relationshipTypes[rType]['placeholder_' + target])
.change();
prepareRelationshipField(val, $contactField);
}
})
.val('')
.change();
$contactField.val('').crmEntityRef({create: true, api: {params: {contact_type: 'Individual'}}});
$contactField.val('').crmEntityRef();
},
post: function(data) {
var contactID = $('[name=add_role_contact_id]', this).val(),
Expand All @@ -114,11 +97,7 @@
},
'#editCaseRoleDialog': {
pre: function(data) {
var params = {create: true};
if (data.contact_type) {
params.api = {params: {contact_type: data.contact_type}};
}
$('[name=edit_role_contact_id]', this).val('').crmEntityRef(params);
prepareRelationshipField(data.rel_type, $('[name=edit_role_contact_id]', this));
},
post: function(data) {
data.rel_contact = $('[name=edit_role_contact_id]', this).val();
Expand Down Expand Up @@ -164,6 +143,31 @@
},
detached = {};

function prepareRelationshipField(relType, $contactField) {
var
pieces = relType.split('_'),
rType = pieces[0],
target = pieces[2], // b or a
relationshipType = CRM.vars.relationshipTypes[rType],
api = {params: {}};
if (relationshipType['contact_type_' + target]) {
api.params.contact_type = relationshipType['contact_type_' + target];
}
if (relationshipType['contact_sub_type_' + target]) {
api.params.contact_sub_type = relationshipType['contact_sub_type_' + target];
}
if (relationshipType['group_' + target]) {
api.params.group = {IN: relationshipType['group_' + target]};
}
$contactField
.data('create-links', !relationshipType['group_' + target])
.data('api-params', api)
.data('user-filter', {})
.attr('placeholder', relationshipType['placeholder_' + target])
.change()
.crmEntityRef();
}

function detachMiniForms() {
detached = {};
$.each(miniForms, function(selector) {
Expand Down
27 changes: 27 additions & 0 deletions tests/phpunit/api/v3/CaseTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,31 @@ public function testCaseStatusByCaseType() {
$this->assertEquals($template['definition']['statuses'], array_values($result['values']));
}

public function testDefinitionGroups() {
$gid1 = $this->groupCreate(['name' => 'testDefinitionGroups1', 'title' => 'testDefinitionGroups1']);
$gid2 = $this->groupCreate(['name' => 'testDefinitionGroups2', 'title' => 'testDefinitionGroups2']);
$def = $this->fixtures['Application_with_Definition'];
$def['definition']['caseRoles'][] = [
'name' => 'Second role',
'groups' => ['testDefinitionGroups1', 'testDefinitionGroups2'],
];
$def['definition']['caseRoles'][] = [
'name' => 'Third role',
'groups' => 'testDefinitionGroups2',
];
$def['definition']['activityAsgmtGrps'] = $gid1;
$createCaseType = $this->callAPISuccess('CaseType', 'create', $def);
$caseType = $this->callAPISuccess('CaseType', 'getsingle', ['id' => $createCaseType['id']]);

// Assert the group id got converted to array with name not id
$this->assertEquals(['testDefinitionGroups1'], $caseType['definition']['activityAsgmtGrps']);

// Assert multiple groups are stored
$this->assertEquals(['testDefinitionGroups1', 'testDefinitionGroups2'], $caseType['definition']['caseRoles'][1]['groups']);

// Assert single group got converted to array
$this->assertEquals(['testDefinitionGroups2'], $caseType['definition']['caseRoles'][2]['groups']);

}

}

0 comments on commit c4a019b

Please sign in to comment.