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

FOSFAB-320: Add Functionality To Link Cases While Creating A New Case #1022

Merged
merged 1 commit into from
Nov 20, 2024
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
145 changes: 145 additions & 0 deletions CRM/Civicase/Hook/Post/LinkCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

use Civi\Api4\CiviCase;
use Civi\Api4\Contact;

/**
* Handles link case logic when case is created.
*/
class CRM_Civicase_Hook_Post_LinkCase {

/**
* Link Cases.
*
* @param string $op
* The operation being performed.
* @param string $objectName
* Object name.
* @param int $objectId
* Object ID.
* @param object $objectRef
* Object reference.
*/
public function run(string $op, string $objectName, ?int $objectId, &$objectRef) {
if (!$this->shouldRun($op, $objectName)) {
return;
}

$linkToCaseId = (int) CRM_Utils_Request::retrieve('linkToCaseId', 'Positive');
$linkedToCaseDetails = $this->getLinkedToCaseDetails($linkToCaseId);
$caseDetails = $this->getCaseDetails($objectId);

$params = [
'case_id' => $linkToCaseId,
'link_to_case_id' => $objectId,
'activity_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Link Cases'),
'medium_id' => CRM_Core_OptionGroup::values('encounter_medium', FALSE, FALSE, FALSE, 'AND is_default = 1'),
'activity_date_time' => date('YmdHis'),
'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_status_id', 'Completed'),
'subject' => $this->getActivitySubject($caseDetails, $linkedToCaseDetails),
'source_contact_id' => \CRM_Core_Session::getLoggedInContactID(),
'target_contact_id' => $linkedToCaseContacts[0]['contact_id'] ?? NULL,
];

$activity = CRM_Activity_BAO_Activity::create($params);

$caseParams = [
'case_id' => $objectId,
'activity_id' => $activity->id,
];
CRM_Case_BAO_Case::processCaseActivity($caseParams);

$caseParams = [
'case_id' => $linkToCaseId,
'activity_id' => $activity->id,
];
CRM_Case_BAO_Case::processCaseActivity($caseParams);
}

/**
* Determines if the hook should run or not.
*
* @param string $op
* The operation being performed.
* @param string $objectName
* Object name.
*
* @return bool
* returns a boolean to determine if hook will run or not.
*/
private function shouldRun(string $op, string $objectName): bool {
return $objectName == 'Case' && $op === 'create'
&& (int) CRM_Utils_Request::retrieve('linkToCaseId', 'Positive') > 0;
}

/**
* Get case details required to create the activity subject.
*
* @param int $id
* The case id.
*
* @return array
* case details.
*/
private function getLinkedToCaseDetails(int $id): array {
$case = CiviCase::get(FALSE)
->addSelect('contact.display_name', 'case_type_id.title')
->addJoin('CaseContact AS case_contact', 'INNER', ['id', '=', 'case_contact.case_id'])
->addJoin('Contact AS contact', 'INNER', ['contact.id', '=', 'case_contact.contact_id'])
->addWhere('id', '=', $id)
->execute()
->first();

return [
'id' => $id,
'caseType' => $case['case_type_id.title'] ?? '',
'contact' => $case['contact.display_name'] ?? '',
];
}

/**
* Get case details required to create the activity subject.
*
* @param int $id
* The case id.
*
* @return array
* case details.
*/
private function getCaseDetails(int $id): array {
$caseClient = Contact::get(FALSE)
->addSelect('display_name')
->addWhere('id', '=', $_POST['client_id'] ?? 0)
->execute()
->first();

return [
'id' => $id,
'caseType' => CRM_Case_BAO_Case::getCaseType($id),
'contact' => $caseClient['display_name'] ?? '',
];
}

/**
* Create activity subject.
*
* @param array $caseDetails
* The case details.
* @param array $linkedToCaseDetails
* The linked to case details.
*
* @return string
* Activity subject.
*/
private function getActivitySubject(array $caseDetails, array $linkedToCaseDetails): string {
return ts('Create link between %1 - %2 (CaseID: %3) and %4 - %5 (CaseID: %6)', [
1 => $caseDetails['contact'],
2 => $caseDetails['caseType'],
3 => $caseDetails['id'],
4 => $linkedToCaseDetails['contact'],
5 => $linkedToCaseDetails['caseType'],
6 => $linkedToCaseDetails['id'],
]);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
(function (angular, $, _) {
var module = angular.module('civicase');

module.service('NewLinkCasesCaseAction', NewLinkCasesCaseAction);

/**
* Create and Link Case Action service
*
* @param {object} $q $q service
* @param {object} ActivityType ActivityType
* @param {string} currentCaseCategory current case category
*/
function NewLinkCasesCaseAction ($q, ActivityType, currentCaseCategory) {
/**
* Click event handler for the Action
*
* @param {object} cases cases
*
* @returns {Promise} promise which resolves to the path for the popup
*/
this.doAction = function (cases) {
var currentCase = cases[0];
var activityTypes = ActivityType.getAll(true);

var link = {
path: 'civicrm/case/add',
query: {
action: 'add',
reset: 1,
atype: _.findKey(activityTypes, { name: 'Open Case' }),
linkToCaseId: currentCase.id,
context: 'standalone',
case_type_category: currentCaseCategory
}
};

return $q.resolve(link);
};
}
})(angular, CRM.$, CRM._);
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
<i class="fa fa-link"></i>
{{ ts('Link Cases') }}
</button>
<button
class="btn btn-large btn-primary"
ng-click="newLinkCase()"
>
<i class="fa fa-link"></i>
{{ ts('Create new linked Case') }}
</button>
</div>
<civicase-case-summary-other-cases
ng-if="item.relatedCases.length"
Expand All @@ -20,10 +27,17 @@
<div class="civicase__activity-card--big--empty-description">
{{ ts('Click the button below to create a new link for this case') }}
</div>
<a
class="civicase__activity-card--big--empty-button btn"
ng-click="linkCase()">
{{ ts('Link Cases') }}
</a>
<div>
<a
class="civicase__activity-card--big--empty-button btn"
ng-click="linkCase()">
{{ ts('Link Cases') }}
</a>
<a
class="civicase__activity-card--big--empty-button btn"
ng-click="newLinkCase()">
{{ ts('Create new linked Case') }}
</a>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
*
* @param {object} $scope the scope object.
* @param {object} LinkCasesCaseAction the link case action service.
* @param {object} NewLinkCasesCaseAction the new link case action service.
* @param {Function} civicaseCrmUrl crm url service.
* @param {Function} civicaseCrmLoadForm service to load civicrm forms
*/
function civicaseCaseDetailsLinkedCasesTabController ($scope,
LinkCasesCaseAction, civicaseCrmUrl, civicaseCrmLoadForm) {
LinkCasesCaseAction, NewLinkCasesCaseAction, civicaseCrmUrl, civicaseCrmLoadForm) {
$scope.linkCase = linkCase;
$scope.newLinkCase = newLinkCase;

/**
* Opens a modal that allows the user to link the case stored in the scope with
Expand All @@ -39,5 +41,20 @@
});
});
}

/**
* Opens a modal that allows the user to open a new case and link it at the same time.
*
* The case details are refreshed after linking the cases.
*/
function newLinkCase () {
NewLinkCasesCaseAction.doAction([$scope.item])
.then(function (openCaseForm) {
civicaseCrmLoadForm(civicaseCrmUrl(openCaseForm.path, openCaseForm.query))
.on('crmFormSuccess crmPopupFormSuccess', function () {
$scope.refresh();
});
});
}
}
})(angular);
1 change: 1 addition & 0 deletions civicase.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ function civicase_civicrm_post($op, $objectName, $objectId, &$objectRef) {
new CRM_Civicase_Hook_Post_PopulateCaseCategoryForCaseType(),
new CRM_Civicase_Hook_Post_CaseCategoryCustomGroupSaver(),
new CRM_Civicase_Hook_Post_UpdateCaseTypeListForCaseCategoryCustomGroup(),
new CRM_Civicase_Hook_Post_LinkCase(),
];

foreach ($hooks as $hook) {
Expand Down
Loading