Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict case roles by group #15570

Merged
merged 3 commits into from
Jan 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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']);

}

}