Skip to content

Commit

Permalink
Merge pull request #19820 from greenpeace-cee/GP-15884-activity-conta…
Browse files Browse the repository at this point in the history
…ct-not-updated

dev/core#2450 - Update source/target contacts on contribution updates
  • Loading branch information
eileenmcnaughton authored Apr 6, 2021
2 parents f501004 + 6b5e660 commit e050cce
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 3 deletions.
52 changes: 49 additions & 3 deletions CRM/Contribute/BAO/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

use Civi\Api4\Activity;
use Civi\Api4\ActivityContact;
use Civi\Api4\Contribution;
use Civi\Api4\ContributionRecur;
use Civi\Api4\PaymentProcessor;
Expand Down Expand Up @@ -533,12 +534,23 @@ public static function create(&$params) {
'id' => $existingActivity['id'] ?? NULL,
], $campaignParams);
if (!$activityParams['id']) {
// Don't set target contacts on update as these will have been
// correctly created and we risk overwriting them with
// 'best guess' params.
$activityParams['source_contact_id'] = (int) ($params['source_contact_id'] ?? (CRM_Core_Session::getLoggedInContactID() ?: $contribution->contact_id));
$activityParams['target_contact_id'] = ($activityParams['source_contact_id'] === (int) $contribution->contact_id) ? [] : [$contribution->contact_id];
}
else {
list($sourceContactId, $targetContactId) = self::getActivitySourceAndTarget($activityParams['id']);

if (empty($targetContactId) && $sourceContactId != $contribution->contact_id) {
// If no target contact exists and the source contact is not equal to
// the contribution contact, update the source contact
$activityParams['source_contact_id'] = $contribution->contact_id;
}
elseif (isset($targetContactId) && $targetContactId != $contribution->contact_id) {
// If a target contact exists and it is not equal to the contribution
// contact, update the target contact
$activityParams['target_contact_id'] = [$contribution->contact_id];
}
}
Activity::save(FALSE)->addRecord($activityParams)->execute();
}

Expand Down Expand Up @@ -5409,4 +5421,38 @@ protected function loadEventMessageTemplateParams(int $eventID, int $participant
return $values;
}

/**
* Get the activity source and target contacts linked to a contribution
*
* @param $activityId
*
* @return array
*/
private static function getActivitySourceAndTarget($activityId): array {
$activityContactQuery = ActivityContact::get(FALSE)->setWhere([
['activity_id', '=', $activityId],
['record_type_id:name', 'IN', ['Activity Source', 'Activity Targets']],
])->execute();

$sourceContactKey = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Source');
$targetContactKey = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Targets');

$sourceContactId = NULL;
$targetContactId = NULL;

for ($i = 0; $i < $activityContactQuery->count(); $i++) {
$record = $activityContactQuery->itemAt($i);

if ($record['record_type_id'] === $sourceContactKey) {
$sourceContactId = $record['contact_id'];
}

if ($record['record_type_id'] === $targetContactKey) {
$targetContactId = $record['contact_id'];
}
}

return [$sourceContactId, $targetContactId];
}

}
79 changes: 79 additions & 0 deletions tests/phpunit/CRM/Contribute/BAO/ContributionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1820,4 +1820,83 @@ public function testContributionQuickConfigTwoLineItems(): void {
$this->assertEquals(0, $count);
}

/**
* Test activity contact is updated when contribution contact is changed
*/
public function testUpdateActivityContactOnContributionContactChange(): void {
$contactId_1 = $this->individualCreate();
$contactId_2 = $this->individualCreate();
$contactId_3 = $this->individualCreate();

$contributionParams = [
'financial_type_id' => 'Donation',
'receive_date' => date('Y-m-d H:i:s'),
'sequential' => TRUE,
'total_amount' => 50,
];

// Case 1: Only source contact, no target contact

$contribution = $this->callAPISuccess('Contribution', 'create', array_merge(
$contributionParams,
['contact_id' => $contactId_1]
))['values'][0];

$activity = $this->callAPISuccessGetSingle('Activity', ['source_record_id' => $contribution['id']]);

$activityContactParams = [
'activity_id' => $activity['id'],
'record_type_id' => 'Activity Source',
];

$activityContact = $this->callAPISuccessGetSingle('ActivityContact', $activityContactParams);

$this->assertEquals($activityContact['contact_id'], $contactId_1, 'Check source contact ID matches the first contact');

$contribution = $this->callAPISuccess('Contribution', 'create', array_merge(
$contributionParams,
[
'id' => $contribution['id'],
'contact_id' => $contactId_2,
]
))['values'][0];

$activityContact = $this->callAPISuccessGetSingle('ActivityContact', $activityContactParams);

$this->assertEquals($activityContact['contact_id'], $contactId_2, 'Check source contact ID matches the second contact');

// Case 2: Source and target contact

$contribution = $this->callAPISuccess('Contribution', 'create', array_merge(
$contributionParams,
[
'contact_id' => $contactId_1,
'source_contact_id' => $contactId_3,
]
))['values'][0];

$activity = $this->callAPISuccessGetSingle('Activity', ['source_record_id' => $contribution['id']]);

$activityContactParams = [
'activity_id' => $activity['id'],
'record_type_id' => 'Activity Targets',
];

$activityContact = $this->callAPISuccessGetSingle('ActivityContact', $activityContactParams);

$this->assertEquals($activityContact['contact_id'], $contactId_1, 'Check target contact ID matches first contact');

$contribution = $this->callAPISuccess('Contribution', 'create', array_merge(
$contributionParams,
[
'id' => $contribution['id'],
'contact_id' => $contactId_2,
]
))['values'][0];

$activityContact = $this->callAPISuccessGetSingle('ActivityContact', $activityContactParams);

$this->assertEquals($activityContact['contact_id'], $contactId_2, 'Check target contact ID matches the second contact');
}

}

0 comments on commit e050cce

Please sign in to comment.